movl $ _start,%eax是什么意思?

Qia*_*ian 7 x86 assembly

'$'后面跟一个标识符是什么意思?

x86汇编,AT&T语法.

zwo*_*wol 12

在AT&T中,语法$意味着将后面的内容视为直接常量而不是内存地址.换一种说法,

movl $_start, %eax
Run Code Online (Sandbox Code Playgroud)

将符号的地址加载_start到%eax;

movl _start, %eax
Run Code Online (Sandbox Code Playgroud)

从内存中读取4个字节_start到%eax 的地址.如果你看看两者的反汇编:

0:  b8 00 00 00 00          mov    $0x0,%eax
        1: R_386_32 _start
5:  a1 00 00 00 00          mov    0x0,%eax
        6: R_386_32 _start
Run Code Online (Sandbox Code Playgroud)

你可以看到唯一的区别是操作码.方便的,有点自私的命名,英特尔 ®64 和IA-32架构软件开发人员手册(你想要第2卷,这是指令集参考)说,操作码B8到BF编码"加载立即16/32位常数到寄存器"(这是注定要加载到32位代码段的代码,所以它是32位加载;对于16位加载,你有一个"操作数大小覆盖"前缀字节,66)和操作码A1编码"在DS(或任何其他段,具有适当的前缀字节)的指定32位偏移处加载32位数量到EAX中." 使用典型的"平坦"内存模型,这就是"在指定的32位绝对地址下加载32位数量"的道德等价物,但您可以看到x86如何在机器级别上获得其可笑的复杂声誉.

如果您想知道,如果我们使用EBX,它就会是这样:

a:  bb 00 00 00 00          mov    $0x0,%ebx
        b: R_386_32 _start
f:  8b 1d 00 00 00 00       mov    0x0,%ebx
       11: R_386_32 _start
Run Code Online (Sandbox Code Playgroud)

Load-immediate仍然可以通过不计算操作数的单字节指令来完成(它是BB而不是B9,正如您所预期的那样,因为内部寄存器顺序是AX,CX,DX,BX,SP,BP, SI,DI - 严重)但是从绝对地址加载现在有一个双字节指令,8B 1D; 第二个字节是英特尔称之为"ModRM"的字节,它指定EBX和后面的绝对4字节地址.