首页 > 解决方案 > x86-64 访问数组的元素

问题描述

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

标签: assemblyx86-64attaddressing-mode

解决方案


是的,它们是不同的。

假设例如%rdi = 0x12340000%r12 = 8。然后movl (%rdi,%r12), %r10d添加%r12to%rdi以形成有效地址,因此您从 address 加载一个 32 位 dword 0x123400084是SIB寻址方式的尺度参数;它会导致%r12在添加 to 之前乘以 4 %rdi,因此movl (%rdi,%r12,4), %r10d您可以从 address 加载一个 32 位 dword 0x12340020

请参阅GNU 手册:“如果未scale指定,scale则视为 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将加载%r10dvalue 5,但movl (%rdi,%r12,4), %r10d将加载 value 17。换句话说,这是一个问题,您是将%rdi其视为字节数还是 32 位整数的计数。

如果它们在您的测试中似乎工作相同,那么您的测试有错误,或者两个不同的地址巧合包含相同的值,或者您%r12的地址为零,或者您的汇编程序损坏(不太可能)。


推荐阅读