我有一小段代码声明了一系列单词,如下所示:
upper_mem: .word 0, 0, 0, 0
现在,我想在每个位置放置寄存器ax,bx,cx,dx的内容,但我不确定标签上的偏移是如何工作的。元素位置是从0开始(如C中)还是1?说我想做:
movw %bx, upper_mem(, 1)
最终会将bx的内容放入第二个单词吗?或者我是用upper_mem(,2)做的吗?
谢谢!
答案 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