【问题标题】:I can't fully understand this assembly code我不能完全理解这个汇编代码
【发布时间】:2019-12-22 23:34:25
【问题描述】:

这是main的汇编代码:

push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %edi,-0x14(%rbp)
mov    %rsi,-0x20(%rbp)
mov    -0x20(%rbp),%rax
add    $0x8,%rax
mov    (%rax),%rax
mov    %rax,%rdi
callq  0x510 <atoi@plt>
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%edx
mov    -0x14(%rbp),%eax
mov    %edx,%esi
mov    %eax,%edi
callq  0x63a <sub>
leaveq 
retq 

这里是C对应的代码:

#include <stdlib.h>
int sub(int x, int y){
        return 2*x+y;
}

int main(int argc, char ** argv){
        int a;
        a = atoi(argv[1]);
        return sub(argc,a);
}

我相信它会在堆栈中分配 20 位,然后它将参数的值从右到左推入 rbp - 14 和 rbp - 20,对吗?为什么需要20位?以及为什么 0x8 被添加到 rax 中?

【问题讨论】:

  • 不可能按位分配任何东西。这里只是减去 0x20。这是对指针的操作,所以这是 32 个字节。这可能被认为是局部变量的空间。不能告诉你为什么它是 32 字节,但也许它有一点帮助。
  • 您忘记启用优化。试图找出未优化代码的细节通常没有用处。由于对齐,通常为 16 个字节,如果省略帧指针,则为 8 个字节。 0x8 是因为你引用了 argv[1] 并且指针是 8 个字节。

标签: assembly x86-64


【解决方案1】:

这是一个带注释的版本: /建立一个栈帧。堆栈必须对齐以符合 ABI, / 所以尽管只需要 2 (*8 = 16) 个位置,4 个 8 字节 (=32) / 位置已保留。 推%rbp 移动 %rsp,%rbp 低于 $0x20,%rsp

/ store away argc, argv for later.
    mov    %edi,-0x14(%rbp)
    mov    %rsi,-0x20(%rbp)
/ get the value of argv[1]:  argv is a vector of char *, so
/ load argv:
    mov    -0x20(%rbp),%rax
/ index by 1:
    add    $0x8,%rax
/ load argv[1].
    mov    (%rax),%rax
/ copy into first parameter of atoi
    mov    %rax,%rdi
    callq  0x510 <atoi@plt>
/ store the result
    mov    %eax,-0x4(%rbp)
/ load parameter 2 of sub:
    mov    -0x4(%rbp),%edx
/ load parameter 1 of sub (argc).
    mov    -0x14(%rbp),%eax
/ move parameters to abi parameter registers
    mov    %edx,%esi
    mov    %eax,%edi
    callq  0x63a <sub>
/ remove stack frame for this function
    leaveq 
    retq 

这个版本去除了多余的负载,为了清楚起见存储:

push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %edi,-0x14(%rbp)
mov    8(%rsi), %rdi
callq  0x510 <atoi@plt>
mov    %eax, %rsi
mov    -0x14(%rbp), %rdi
callq  0x63a <sub>
leaveq 
retq 

【讨论】:

  • 你的解释很清楚,谢谢。
  • 除了对齐要求是 16 个字节,因此不需要额外的 16 个字节。它们只是未优化代码的结果。通过删除帧指针和使用尾调用优化,甚至可以进一步减少您的版本。
猜你喜欢
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
  • 2019-12-25
  • 2021-07-25
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多