嗨,我是汇编语言的初学者,movl (%rdi,%r12), %r10d和movl (%rdi,%r12,4), %r10d有什么区别吗?我尝试了这两种方法,它们似乎都做了相同的工作--将%r12位置上的%rdi元素保存到%r10d。第二个例子中的4真的有必要吗?
发布于 2020-10-19 22:36:59
是的,它们是不同的。
例如,假设%rdi = 0x12340000和%r12 = 8。然后movl (%rdi,%r12), %r10d将%r12添加到%rdi中以形成有效地址,因此您可以从address 0x12340008加载32位dword。4是SIB寻址模式的缩放参数;它使%r12在添加到%rdi之前被乘以4,因此对于movl (%rdi,%r12,4), %r10d,您可以从address 0x12340020加载32位dword。
请参见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将用值5加载%r10d,而movl (%rdi,%r12,4), %r10d将用值17加载%r10d。换句话说,这是一个问题,您是将%rdi视为字节计数,还是将32位ints计数。
如果它们在您的测试中显示为相同的工作方式,那么要么您的测试是错误的,要么这两个不同的地址碰巧包含相同的值,或者您的%r12为零,或者您的汇编程序坏了(不可能)。
https://stackoverflow.com/questions/64435433
复制相似问题