无法理解汇编代码中的基址指针计算
我想通过反汇编程序来了解以下函数的汇编代码。我无法得到为什么所有的操作都与基指针有关。无法理解汇编代码中的基址指针计算
为什么的
rcx
和rdx
寄存器值移动到存储位置10和18的偏移? (mov 0x10(%rbp),%rax
和mov %rdx,0x18(%rbp)
)。为什么存储在
mov %rax,-0x8(%rbp)
long absdiff(long x, long y)
{
long result;
if (x>y)
result = x-y;
else
result = y-x;
return result;
}
0x00000001004010e0 <+0>: push %rbp
0x00000001004010e1 <+1>: mov %rsp,%rbp
0x00000001004010e4 <+4>: sub $0x10,%rsp
0x00000001004010e8 <+8>: mov %rcx,0x10(%rbp)
0x00000001004010ec <+12>: mov %rdx,0x18(%rbp)
0x00000001004010f0 <+16>: mov 0x10(%rbp),%rax
0x00000001004010f4 <+20>: cmp 0x18(%rbp),%rax
0x00000001004010f8 <+24>: jle 0x100401108 <absdiff+40>
0x00000001004010fa <+26>: mov 0x10(%rbp),%rax
0x00000001004010fe <+30>: sub 0x18(%rbp),%rax
0x0000000100401102 <+34>: mov %rax,-0x8(%rbp)
0x0000000100401106 <+38>: jmp 0x100401114 <absdiff+52>
0x0000000100401108 <+40>: mov 0x18(%rbp),%rax
0x000000010040110c <+44>: sub 0x10(%rbp),%rax
0x0000000100401110 <+48>: mov %rax,-0x8(%rbp)
0x0000000100401114 <+52>: mov -0x8(%rbp),%rax
0x0000000100401118 <+56>: add $0x10,%rsp
0x000000010040111c <+60>: pop %rbp
0x000000010040111d <+61>: retq
1)为什么sub $0x10, %rsp
的返回值?
它实际上是减去16个字节,换句话说,它为两个“长”参数的制作空间。尝试打印'sizeof(long)',我很肯定你会在你正在使用的机器上得到'8'作为答案。
2)为什么要将寄存器值移到内存中?
再次,这是计算机将寄存器'rcx'和'rdx'中的两个长值加载到它在'1)'中创建的内存空间中的位置。 0x10和0x18有8个字节的差异。
3)为什么返回值存储在mov %rax,-0x8(%rbp)
?
它是暂时存储的,因为在离开函数之前,%rax寄存器用于其他一些计算。因此,如果它没有保存,它会被覆盖,你可以看到,在这些计算完成后,该值再次被加载到rax中。
mov%rax,-0x8(%rbp) <--- saving
jmp 0x100401114 <absdiff+52>
...
mov %rax,-0x8(%rbp)
-0x8(%rbp),%rax" < -- retrieving
一个建议
我敢肯定你会发现这个链接真的很有帮助:
https://www.recurse.com/blog/7-understanding-c-by-learning-assembly
请尽力而为正确格式化您的答案。那么你会从我这里得到赞扬。 –
有!感谢你的咆哮,它真的很有用。和平! (y) –
这是否不覆盖已存在于内存位置的任何内容(rbp) - 8?或者该位置已被分配给该功能? mov%rax,-0x8(%rbp) – user2927392
_why是减去10个字节_....... ...'0x10 = 16' ..... – LPs
您应该开始识别汇编代码中代表'x'和'y'的方式。你为什么期望从堆栈指针中减去8?提示:这是作为一个64位程序编译的。 –
我建议编译启用优化。该程序集将*更短,更易于理解。 – EOF