assembly - 初学者 : Can't decode this assembly code

标签 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:这里的内容真正让我困惑。我们将 %rdi (0 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 上运行 x/s $rbp-0x28 来查看 -0x28(%rbp) 中的内容时,我没有得到 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?这不是重复了吗?

非常感谢!我知道这真的很长,感谢您花时间帮助我!

最佳答案

你的分析是正确的。

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

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

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

关于assembly - 初学者 : Can't decode this assembly code,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13080647/

相关文章:

assembly - x86组装-将rax夹紧到[0 .. limit)的优化

assembly - 为什么 x86 int 寄存器的数量是 8 个?

c - 当另一个静态数组溢出时覆盖堆栈静态数组

c - 使用数组实现堆栈

c++ - 在 x64 进程中调用 x86 winapi 函数

windows - 适用于 Windows 64 位的 osm2pgsql 最新版本在哪里

macos - OS X - x64 : stack not 16 byte aligned error

C++ - 将 C 字符串推送到模板堆栈

c++ - 非常大的枚举器(> 64 位类型)

assembly - 6502 寄存器加载(LDA、LDX、LDY)是否会在立即寻址模式下修改 N 和 Z 标志?