1

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

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

例如:

mov %eax, -100(%eax)

jmp 100 
jmp $100, $100

是不同的。

我的问题是为什么$前缀如此混乱?

4

2 回答 2

2

jmp 100是跳转到绝对地址 100,就像jmp my_label跳转到my_label. EIP = 100 或 EIP = 的地址my_label

(通过重定位jmp 100汇编为 a ,要求链接器填写从指令自身地址到绝对目标的正确相对偏移量。)jmp rel32R_386_PC32jmp

因此,在 AT&T 语法中,您可以将其jmp x视为 EIP 中的 LEA。

或者另一种思考方式是代码获取从指定的内存位置开始。立即要求 a$并没有什么意义,因为直接近跳的机器编码使用相对位移,而不是绝对位移。(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将立即数编码到指令中一样。

于 2018-09-16T21:06:35.267 回答
0

问题:我的问题是为什么前缀 $ 如此混乱?

$ 前缀用于按原样加载/使用值。

例子:

 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”的特定内存位置的符号表示。

我希望以上内容可以消除您的困惑。

于 2013-09-10T06:14:21.203 回答