ash*_*ish 3 x86 assembly memory-segmentation
我正在学习英特尔手册中的计算机体系结构。我的理解是,我们给出的指令是由段选择器和偏移量组成的逻辑地址。它基本上是CS register<<4 + offset。在Segment Selector映射到GDT或LDT为在给定TI的段选择的位。GDT 由Segment Descriptorshave BASE, LIMITand组成,RPL输出是基地址。这个base address+offset提供了logical address.
什么是决定段寄存器(其中的规则SS,DS等),适用于不同的存储操作?例如,什么决定了哪个段用于mov eax, [edi]?
代码提取总是使用CS.
数据寻址模式默认为DS(或SS当 EBP 或 ESP 为基址寄存器时)在“正常”寻址模式中。(例如mov eax, [edi],相当于[ds:edi],mov eax, [ebp+edi*4]相当于mov eax, [ss: ebp + edi*4])。
(一些反汇编程序即使在默认情况下也会使段显式,因此您会看到大量DS:混乱的反汇编输出。(您可以使用段覆盖前缀来选择哪个段将应用于指令中的内存操作数。)在 NASM 中语法,显式使用[ds:edi]寻址模式将导致ds机器代码中出现冗余前缀。)
一些带有隐式内存操作数的指令有不同的默认值:
一些字符串指令ES:EDI隐式使用。例如,该movs指令读取[DS:ESI]和写入[ES:EDI],从而可以轻松地在没有段覆盖前缀的情况下在段之间进行复制。
使用存储器操作数esp或ebp作为基址寄存器默认到SS,因此堆栈的指令等执行隐式访问push/ pop/ call/ ret。
FS并且GS从来都不是默认值,因此它们可以在现代 32 位和 64 位操作系统等平面内存模型系统中用于特殊目的(如线程本地存储)。
这也正式记录在英特尔的 ISA 手册中。例如在第 2 卷(指令集参考)中,表 2-1。带有 ModR/M 字节的 16 位寻址形式有一个脚注说:
默认段寄存器是包含 BP 索引的有效地址的 SS,其他有效地址的 DS。
(请注意,SP 不是 16 位寻址模式的有效基地址。
另请注意,当他们说“索引”时,这意味着根本使用 BP 时,甚至用于[bp + si]or [bp+di]。在 32 位和 64 位寻址模式中, base 和 index 之间有更明显的区别,[symbol + ebp*4]仍然暗示 DS 作为段,因为 EBP 用作索引,而不是base。)
对于 32 位或 64 位寻址模式没有等效的脚注,因此详细信息必须在手册的另一卷中。
另请参阅x86标记 wiki 以获取更多链接。