我试图通过执行反汇编程序来理解以下函数的汇编代码。我无法理解为什么所有操作都相对于基指针。
为什么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
答案 0 :(得分:4)
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