2017-07-06 122 views
-1

我想通过反汇编程序来了解以下函数的汇编代码。我无法得到为什么所有的操作都与基指针有关。无法理解汇编代码中的基址指针计算

  1. 为什么的rcxrdx寄存器值移动到存储位置10和18的偏移? (mov 0x10(%rbp),%raxmov %rdx,0x18(%rbp))。

  2. 为什么存储在 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 
+3

_why是减去10个字节_....... ...'0x10 = 16' ..... – LPs

+0

您应该开始识别汇编代码中代表'x'和'y'的方式。你为什么期望从堆栈指针中减去8?提示:这是作为一个64位程序编译的。 –

+0

我建议编译启用优化。该程序集将*更短,更易于理解。 – EOF

回答

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

+1

请尽力而为正确格式化您的答案。那么你会从我这里得到赞扬。 –

+0

有!感谢你的咆哮,它真的很有用。和平! (y) –

+0

这是否不覆盖已存在于内存位置的任何内容(rbp) - 8?或者该位置已被分配给该功能? mov%rax,-0x8(%rbp) – user2927392