x86-64 访问数组元素

x86-64 accessing element of array

你好我是汇编语言的初学者,movl (%rdi,%r12), %r10d movl (%rdi,%r12,4), %r10d有区别吗?我尝试了他们两个,他们似乎都在做同样的工作——将 %rdi 的元素在 %r12 位置保存到 %r10d。第二个例子中的4真的有必要吗?

是的,它们是不同的。

例如假设 %rdi = 0x12340000%r12 = 8。然后 movl (%rdi,%r12), %r10d%r12 添加到 %rdi 以形成有效地址,因此您从地址 0x12340008 加载一个 32 位双字。 4为SIB寻址方式的比例参数;它会导致 %r12 在添加到 %rdi 之前乘以 4,因此使用 movl (%rdi,%r12,4), %r10d 您可以从地址 0x12340020 加载一个 32 位双字。

参见GNU as manual:“如果没有指定scalescale被认为是1。”

如果您尝试使用定义为

的数组
int32_t foo[] = {1,3,5,7,9,11,13,15,17,19,21,23,25};

%rdi包含foo的地址,如上%r12 = 8,则movl (%rdi,%r12), %r10d将加载%r10d的值为5,但 movl (%rdi,%r12,4), %r10d 将使用值 17 加载它。换句话说,问题在于您是将 %rdi 视为字节计数还是 32 位整数计数。

如果它们在您的测试中看起来工作相同,那么要么您的测试有问题,要么两个不同的地址碰巧包含相同的值,或者您的 %r12 为零,或者您的汇编程序坏了(不太可能)。