对AT&T汇编语法感到困惑,用于寻址模式与jmp和远jmp

问题描述 投票:1回答:2

在AT&T程序集语法中,文字值必须以$符号为前缀

但是,在内存寻址中,文字值没有$符号

例如:

mov %eax, -100(%eax)

jmp 100 
jmp $100, $100

是不同的。

我的问题是为什么$前缀如此令人困惑?

linux x86 intel gas att
2个回答
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”。

我希望上面的内容能够解决你的困惑。


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:32jmp m16:32都有32位模式,所以你需要区分ljmp *(%edi)ljmp $100, $100

直接跳远(jmp far ptr16:32)确实采用绝对段:偏移编码到指令中,就像add $123, %eax立即编码到指令中一样。

© www.soinside.com 2019 - 2024. All rights reserved.