【发布时间】:2018-01-17 12:06:09
【问题描述】:
我要考试了,我正在努力组装。我已经编写了一些简单的 C 代码,得到了它的汇编代码,然后尝试对汇编代码进行评论作为练习。 C代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
int x = 10;
char const* y = argv[1];
printf("%s\n",y );
return 0;
}
它的汇编代码:
0x00000000000006a0 <+0>: push %rbp # Creating stack
0x00000000000006a1 <+1>: mov %rsp,%rbp # Saving base of stack into base pointer register
0x00000000000006a4 <+4>: sub $0x20,%rsp # Allocate 32 bytes of space on the stack
0x00000000000006a8 <+8>: mov %edi,-0x14(%rbp) # First argument stored in stackframe
0x00000000000006ab <+11>: mov %rsi,-0x20(%rbp) # Second argument stored in stackframe
0x00000000000006af <+15>: movl $0xa,-0xc(%rbp) # Value 10 stored in x's address in the stackframe
0x00000000000006b6 <+22>: mov -0x20(%rbp),%rax # Second argument stored in return value register
0x00000000000006ba <+26>: mov 0x8(%rax),%rax # ??
0x00000000000006be <+30>: mov %rax,-0x8(%rbp) # ??
0x00000000000006c2 <+34>: mov -0x8(%rbp),%rax # ??
0x00000000000006c6 <+38>: mov %rax,%rdi # Return value copied to 1st argument register - why??
0x00000000000006c9 <+41>: callq 0x560 # printf??
0x00000000000006ce <+46>: mov $0x0,%eax # Value 0 is copied to return register
0x00000000000006d3 <+51>: leaveq # Destroying stackframe
0x00000000000006d4 <+52>: retq # Popping return address, and setting instruction pointer equal to it
无论我有什么“??”,一个友好的灵魂可以帮助我吗? (意思是我不明白发生了什么或者我不确定)?
【问题讨论】:
-
如果你的课程是汇编编程,阅读编译器生成的代码不会有帮助。在您的教育的这个阶段,这可能是有害的。
-
你可以尝试使用
gcc -c -S -fverbose-asm file.c- 应该生成带有注释ASM的file.s -
它有助于使用调试器单步通过汇编程序,注意寄存器、内存等操作。
-
@StoryTeller 我即将举行的考试将有“用 C 重写上述 X86 汇编程序”之类的问题,所以我想通过反过来练习我可以受益。
-
您还应该检查编译器的优化输出,您当前的程序集未优化 -O0 在每行源代码之后更新堆栈框架和局部变量,以使 C 源代码中的“每行”调试成为可能,机器代码没有该功能生成将有很大不同(也更短,并且从纯汇编的角度可能更容易理解......并且更难以重写回C源代码,此时您基本上必须执行 asm -> algorithm - > 从头开始编写 C,而未优化的代码几乎可以通过 asm->C 反向翻译来重构)。