在汇编语言中,"DS:[40207A]"是什么意思?

36
0040103A   CALL DWORD PTR DS:[40207A]                USER32.MessageBoxA

什么是DS:的含义?

2个回答

40
该指令从内存中的ds:[40207A]加载一个新的EIP值。也就是说,地址40207A处有一个函数指针。(并且它会推送一个返回地址,因为这是一个call而不仅仅是一个jmp。) ds:表示该指令正在引用数据段内存,在现代操作系统上可以基本忽略,因为它们使用平面地址空间模型运行(代码、数据和堆栈段都引用同一内存范围,并且内存保护通过分页处理)。 ds:在这里是为了向您表明它绝对是一个内存操作数,并提醒您它使用的是哪个段/显示它没有段覆盖前缀(除非已经是默认的ds前缀)。

编辑:

稍作解释-请注意,为了简单起见,这是在运行Windows的32位保护模式下的上下文中。
段寄存器(CS、DS、SS、ES、FS、GS)保存一个指向描述符的选择器。有两个描述符表:全局(GDT)和本地(LDT),选择器有一个位指示使用哪个表。Windows(几乎?)专门使用全局表。

descriptor 基本上是一个 {开始地址,大小} 对 - 当然还有更多内容,但不在此帖子的范围内。

Windows 使用 Flat Memory Model: 每个进程具有从内存地址 0 开始的 4GB 地址空间,并使用 paging 来使进程彼此隔离。

由于进程具有这种扁平的世界观,它们运行时所有段都使用 {0, 4GB} 描述符 - 因此,Windows 不需要为每个进程分配描述符,只需使用少量全局描述符即可。

编辑2:

Portable Executable 格式定义了 sections,与 x86 segments 无关 - 即使存在一些概念上的重叠。PE EXE 可以拥有几乎任何你想要的节(Section)布局,但通常将其分为代码(读/执行)、数据(读/写)、资源(只读?)等部分。将可执行文件拆分为节可以对内存范围应用 x86 页面级内存保护。

编辑3:

普通段不会因为进程而改变,Windows使用FS寄存器指向每个线程的TIB结构。

编辑4:

请参阅此处以获取概述。这是关于80386的旧文档,但信息仍然适用。


4
PE可执行文件有多个“节(section)”,但这些与x86“段(segment)”无关。 - snemarch
我一直以为它们是同一件事,你能详细解释一下它们的区别吗? - wamp
不,CPU 有内部 GDTR/LDTR 寄存器,可以通过 LGDT/SGDT,LLDT/SLDT 指令访问。FS 和 GS 是在 80386 中引入的额外段,在 CPU 中没有固有意义;之所以选择这些名称是因为我们已经有了 ES("Extra" Segment)。 - snemarch
对于所有普通应用程序,是的。 - snemarch
这已经偏离主题了。在正常情况下,我没有看到段寄存器在用户模式下发生变化。 - snemarch
显示剩余4条评论

5

内存地址由段和偏移量组成;DS是“数据段”寄存器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接