我正在考试,我正忙着装配。我编写了一些简单的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
友善的灵魂可以帮助我,无论我在哪里“??” (意思是我不明白发生了什么或者我不确定)?
答案 0 :(得分:4)
0x00000000000006ba <+26>: mov 0x8(%rax),%rax # get argv[1] to rax
0x00000000000006be <+30>: mov %rax,-0x8(%rbp) # move argv[1] to local variable
0x00000000000006c2 <+34>: mov -0x8(%rbp),%rax # move local variable to rax (for move to rdi)
0x00000000000006c6 <+38>: mov %rax,%rdi # now rdi has argv[1]
0x00000000000006c9 <+41>: callq 0x560 # it is puts (optimized)
答案 1 :(得分:2)
我会试着猜一下:
mov -0x20(%rbp),%rax # retrieve argv[0]
mov 0x8(%rax),%rax # store argv[1] into rax
mov %rax,-0x8(%rbp) # store argv[1] (which now is in rax) into y
mov -0x8(%rbp),%rax # put y back into rax (which might look dumb, but possibly it has its reasons)
mov %rax,%rdi # copy y to rdi, possibly to prepare the context for the printf
当您处理汇编程序时,请指定您正在使用的架构。英特尔处理器可能使用来自ARM的不同指令集,相同的指令可能不同,或者它们可能依赖于不同的假设。您可能知道,优化会更改编译器生成的汇编程序指令的顺序,您可能希望指定是否也使用它(看起来不是?)以及您使用的编译器,因为每个人都有自己的生成汇编程序的策略
也许我们永远不会知道为什么编译器必须通过从rax复制来为printf准备上下文,它可能是编译器的选择或特定架构强加的义务。出于所有这些恼人的原因,大多数人更喜欢使用高级语言&#34;比如C,所以指令集始终是正确的,虽然对于人类来说可能看起来很愚蠢(因为我们知道计算机在设计上是愚蠢的)而且并不总是最多的选择,这就是为什么还有很多编译器的原因周围。
我可以再给你两个提示:
IDE必须能够将汇编程序指令与C代码交错,并在汇编程序中单步执行。试着找出来并自己探索
IDE还应具有探索程序内存的功能。如果你发现尝试输入0x560地址,那么它会引导你。这很可能是printf
我希望我的回答可以帮助你解决问题,祝你好运