assembly - 默认使用哪个段寄存器?

标签 assembly x86 memory-segmentation

我正在学习英特尔手册中的计算机体系结构。据我了解,我们给出的指令是逻辑地址,由段选择器和偏移量组成。 它基本上是 CS register<<4 + offset . Segment Selector映射到 TI 中给出的 GDTLDT段选择器的位。 GDT 由 Segment Descriptors 组成其中有 BASE , LIMITRPL输出是基地址。这base address + offset提供 logical address .

决定哪个段寄存器(SSDS 等)适用于不同的内存操作的规则是什么?例如是什么决定了哪个段用于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 instruction[DS:ESI] 读取并写入 [ES:EDI],从而可以轻松地在没有段覆盖前缀的段之间进行复制。

使用 espebp 作为基址寄存器的内存操作数默认为 SS,堆栈指令的隐式访问也是如此,例如 push/pop/call/ret.

FSGS 从来都不是默认值,因此它们可以在平面内存模型系统(如现代 32 和64 位操作系统。

wikipedia explains the same thing here


这也在 Intel's ISA manuals 中正式记录。例如在第 2 卷(指令集引用)中,表 2-1。带有 ModR/M 字节的 16 位寻址形式 有一个脚注说:

The default segment register is SS for the effective addresses containing a BP index, DS for other effective addresses.

(注意 SP 不是 16 位寻址模式的有效基地址。
另请注意,当他们说“索引”时,这意味着完全使用 BP,即使是 [bp + si][bp+di]。在32位和64位寻址方式下,base和index的区别比较明显,[symbol + ebp*4]仍然隐含DS为段,因为EBP是作为index使用的,不是基地。)

对于 32 位或 64 位寻址模式没有等效的脚注,因此详细信息必须在手册的另一卷中。

另请参阅 标签 wiki 以获得更多链接。

关于assembly - 默认使用哪个段寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38843403/

相关文章:

c - 同步原语的简单/规范实现?

c - 如何正确地将汇编程序转换为shellcode?

c - 编译器在函数名称前加下划线的原因是什么?

assembly - 段寄存器的汇编程序使用

x86 - 使用GDB读取MSR

assembly - 以 1ms 为增量获取时间

c++ - VC++ 2010 - 尝试 DLL 时未声明的标识符,少量代码

x86 - BIOS 和地址 0x07C00

assembly - 多核汇编语言是什么样的?

c++ - Segmentation fault (core dumped) - 无法修复错误