繁体   English   中英

无法理解此汇编代码

[英]Trouble understanding this assembly code

我即将要参加考试,并且正在为组装苦苦挣扎。 我已经编写了一些简单的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

友善的灵魂可以在任何有我的地方帮助我吗? (这意味着我不了解发生了什么或不确定)。

   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)

我将尝试做出一个猜测:

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准备上下文,这可能是编译器的选择,也可能是特定体系结构所施加的义务。 由于所有这些令人讨厌的原因,大多数人都喜欢使用“高级语言”(例如C),尽管这对人类来说可能看起来非常愚蠢(尽管我们知道计算机在设计上是愚蠢的),但指令集始终是正确的并非总是最好的选择,这就是为什么仍然有很多编译器的原因。

我可以再给您两个提示:

  1. 您的IDE必须有一种方法将汇编程序指令与C代码交织在一起,并在汇编程序内进行单步执行。 尝试找出并自己探索

  2. IDE还应该具有探索程序内存的功能。 如果您发现尝试输入0x560地址并查看是否会引导您。 这很有可能是您的printf的切入点

希望我的回答能帮助您解决问题,祝您好运

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM