初学者:无法解码此汇编代码

时间:2012-10-26 04:17:24

标签: assembly stack 64-bit cpu-registers

我是汇编语言的新手,我正在尝试解码从二进制文件生成的汇编文件(使用gdb)。我无法理解以下代码(这是新功能的开始)。我在x64机器上,%rdi保持6位数(我的输入)。所以,我们只说0 1 2 3 4 5

   400e79:       55                      push   %rbp
   400e7a:       48 89 e5                mov    %rsp,%rbp
   400e7d:       48 83 ec 30             sub    $0x30,%rsp
   400e81:       48 89 7d d8             mov    %rdi,-0x28(%rbp)
   400e85:       48 8d 75 e0             lea    -0x20(%rbp),%rsi
   400e89:       48 8b 7d d8             mov    -0x28(%rbp),%rdi

如果可以的话,我想告诉你我的想法:

400e79:所以当我们启动一个函数时,我们将旧的基指针推到堆栈上。所以堆栈看起来像:

 RETURN ADDRESS
 old %rbp value  <--- %rsp

400e7a:堆栈看起来像:

 RETURN ADDRESS
 old %rbp value <---- %rsp, %rbp

400e7d:堆栈看起来像:

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 ----empty----  <---%rsp

400e81:来自这里的东西让我很困惑。我们正在将%rdi0 1 2 3 4 5)中的内容移至-0x28(%rbp)。所以堆栈看起来像:

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 0 1 2 3 4 5
 ----empty----  <---%rsp

但是,当我尝试通过在gdb上运行-0x28(%rbp)来查看x/s $rbp-0x28中的内容时,我没有像我期望的那样得到0 1 2 3 4 5,但我得到了"\020C" }。我运行正确吗?

400e85:筹码:

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty---- <--- %rsi
 0 1 2 3 4 5
 ----empty----  <---%rsp

400e89:我根本不明白这一点。我们之前刚刚mov %rdi,-0x28(%rbp),为什么我们现在正在做mov -0x28(%rbp),%rdi?这不重复吗?

非常感谢!我知道这真的很长,感谢你抽出时间帮助我!

1 个答案:

答案 0 :(得分:2)

您的分析是正确的。

运行x/s $rbp-0x28时得到奇怪结果的原因是你不能将字符串放在寄存器中。寄存器包含的值很可能是指向该字符串的指针,这意味着您需要另一级别的间接读取它。我相信这会奏效:

p/x *(char**)($rbp-0x28)
x/s $

对于无用的负载,这对于没有优化编译的代码来说很常见。编译器盲目地将每一行转换为汇编而不考虑当前寄存器值。我见过代码,它通过几个寄存器将一个值传递回原来的寄存器。