【问题标题】:Label offsetting in x86 GASx86 GAS 中的标签偏移
【发布时间】:2014-10-15 14:51:09
【问题描述】:

我有一小段代码声明了一个单词数组,如下所示:

upper_mem: .word 0, 0, 0, 0

现在,我想将寄存器 ax、bx、cx、dx 的内容放置在每个位置,但我不确定标签上的偏移是如何工作的。元素位置是从 0(如 C 语言)还是从 1 开始?说我想做:

movw %bx, upper_mem(, 1)

最终会将 bx 的内容放入第二个单词中吗?还是我用 upper_mem(, 2) 来做?

谢谢!

【问题讨论】:

    标签: assembly x86 gnu-assembler


    【解决方案1】:

    movw %bx, upper_mem(, 1) 无论如何不是 C 术语upper_mem[1] 的挂件。这是一个语法异常,等效于movw %bx, (upper_mem) (https://sourceware.org/binutils/docs/as/i386_002dMemory.html#i386_002dMemory)。

    使用关键字 .word 和以下四个值,您在内存中保留了 4 个字(= 8 个字节)的位置,但汇编器不会记住它。寻址保持按字节。第一个 2 字节元素位于 [memory+0],第二个 2 字节元素位于 [memory+2],依此类推。如果你从 [memory+1] 加载一个单词,你会得到第一个元素的一半和第二个元素的一半。类似 C 的索引的一种方法是在您的情况下将索引寄存器缩放(即乘以)2。

    希望下面的例子能指出来:

    # Name:             test.s
    # Assemble & link:  gcc -m32 test.s
    # Run:              ./a.out
    
    .global main
    
    .data
        upper_mem: .word 0, 0, 0, 0
        fmt: .asciz "%d %d %d %d\n"
    
    .text
    main:
        mov $10, %ax
        mov $20, %bx
        mov $30, %cx
        mov $40, %dx
    
    # https://sourceware.org/binutils/docs/as/i386_002dMemory.html#i386_002dMemory
        movl $0, %edi
        movw %ax, upper_mem(,%edi,2)
        movl $1, %edi
        movw %bx, upper_mem(,%edi,2)
        movl $2, %edi
        movw %cx, upper_mem(,%edi,2)
        movl $3, %edi
        movw %dx, upper_mem(,%edi,2)
    
    # https://sourceware.org/binutils/docs/as/i386_002dMnemonics.html#i386_002dMnemonics
        movzwl (upper_mem), %eax
        movzwl (upper_mem+2), %ebx
        movzwl (upper_mem+4), %ecx
        movzwl (upper_mem+6), %edx
    
        pushl %edx
        pushl %ecx
        pushl %ebx
        pushl %eax
        pushl $fmt
        call printf
        addl $20,%esp
    
        xor %eax, %eax
        ret
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      相关资源
      最近更新 更多