在AT& T程序集语法中,文字值必须以$
符号为前缀
但是,在内存寻址中,文字值没有$
符号
例如:
mov %eax, -100(%eax)
和
jmp 100
jmp $100, $100
是不同的。
我的问题是为什么$
前缀如此令人困惑?
答案 0 :(得分:0)
问题:我的问题是为什么前缀$如此困惑?
$ prefix用于按原样加载/使用该值。
示例:
movl $5, %eax #copy value 5 to eax
addl $10,%eax # add 10 + 5 and store result in eax
$ 5,$ 10是值(常量),不能从寄存器或内存等任何外部源获取
在内存寻址中,特别是“直接寻址模式”,我们希望使用存储在特定内存位置的值。
示例:
movl 20, %eax
以上将使存储在位置的值为20。
由于内存位置以十六进制(0x00000000到0xfffffffff)编号,因此很难在指令中以十六进制指定内存位置。所以我们为位置
分配一个符号示例:
.section .data
mydata:
long 4
.section .text
.globl _start
_start
movl mydata, %eax
在上面的代码中,mydata是给定特定存储位置的符号表示,其中存储值“4”。
我希望上述内容能够解决您的困惑。
答案 1 :(得分:0)
jmp 100
是跳转到绝对地址100,就像jmp my_label
是跳转到my_label
上的代码一样。 EIP = 100或EIP = my_label
的地址。
({jmp 100
组合成jmp rel32
重定位的R_386_PC32
,要求链接器填写从jmp
指令自己的地址到绝对目标的正确相对偏移量)
因此,在AT&T语法中,您可以将jmp x
视为EIP中的LEA。
另一种思考方式是代码获取从指定的内存位置开始。要求$
立即执行是没有意义的,因为直接近跳的机器编码使用相对位移,而不是绝对位移。 (http://felixcloutier.com/x86/JMP.html)。
此外,间接跳转使用不同的语法(jmp *%eax
间接寄存器或jmp *(%edi, %ecx, 4)
间接内存),因此不需要在立即数和内存之间进行区分。
但是远跳是另一回事。
jmp ptr16:32
和jmp m16:32
都可以在32位模式下使用,因此您需要区分ljmp *(%edi)
与ljmp $100, $100
。
直接远跳(jmp far ptr16:32
)确实占用了绝对段:偏移量已编码到指令中,就像add $123, %eax
会将立即数编码到指令中一样。