x86 GAS中的标签偏移

时间:2014-10-15 14:51:10

标签: assembly x86 gas

我有一小段代码声明了一系列单词,如下所示:

upper_mem: .word 0, 0, 0, 0

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

movw %bx, upper_mem(, 1)

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

谢谢!

1 个答案:

答案 0 :(得分:4)

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