【问题标题】:Confused about AT&T Assembly Syntax for addressing modes vs. jmp and far jmp对用于寻址模式与 jmp 和 far jmp 的 AT&T 汇编语法感到困惑
【发布时间】:2013-07-17 02:33:15
【问题描述】:

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

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

例如:

mov %eax, -100(%eax)

jmp 100 
jmp $100, $100

不同。

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

【问题讨论】:

    标签: linux x86 intel gnu-assembler att


    【解决方案1】:

    jmp 100 是跳转到绝对地址 100,就像 jmp my_label 是跳转到 my_label 处的代码一样。 EIP = 100 或 EIP = my_label 的地址。

    jmp 100 汇编为带有R_386_PC32 重定位的jmp rel32,要求链接器填写从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 将立即数编码到指令中一样。

    【讨论】:

      【解决方案2】:

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

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

      示例:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-09
        • 2019-01-20
        • 1970-01-01
        • 1970-01-01
        • 2018-11-10
        • 1970-01-01
        • 2014-10-04
        • 1970-01-01
        相关资源
        最近更新 更多