简体   繁体   English

无法理解此汇编代码

[英]Trouble understanding this assembly code

I have an exam comming up, and I'm strugling with assembly. 我即将要参加考试,并且正在为组装苦苦挣扎。 I have written some simple C code, gotten its assembly code, and then trying to comment on the assembly code as practice. 我已经编写了一些简单的C代码,获得了其汇编代码,然后尝试对汇编代码进行评论。 The C code: 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;
}

Its assembly code: 其汇编代码:

   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

Can a friendly soul help me out wherever I have "??" 友善的灵魂可以在任何有我的地方帮助我吗? (meaning I don't understand what is happening or I'm unsure)? (这意味着我不了解发生了什么或不确定)。

   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)

I will try to make a guess: 我将尝试做出一个猜测:

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

When you deal with assembler, please specify which architecture you are using. 处理汇编程序时,请指定要使用的体系结构。 An Intel processor might use a different set of instructions from an ARM one, the same instructions might be different or they might rely on different assumptions. 英特尔处理器使用的指令集可能与ARM使用的指令集不同,相同的指令可能不同,或者可能依赖于不同的假设。 As you might know, optimisations change the sequence of assembler instructions generated by the compiler, you might want to specify whether you are using that as well (looks like not?) and which compiler you are using as everyone has its own policy for generating assembler. 如您所知,优化会更改编译器生成的汇编程序指令的顺序,您可能希望指定是否也正在使用该指令(看起来像不是?),以及所使用的编译器,因为每个人都有自己的生成汇编程序的策略。 。

Maybe we will never know why the compiler must prepare the context for printf by copying from rax, it could be a compiler's choice or an obligation imposed by the specific architecture. 也许我们永远不会知道为什么编译器必须通过从rax复制来为printf准备上下文,这可能是编译器的选择,也可能是特定体系结构所施加的义务。 For all those annoying reasons, most of people prefer to use a "high level language" such as C, so that the set of instructions is always right although it might look very dumb for a human (as we know computers are dumb by design) and not always the most choice, that's why there are still many compilers around. 由于所有这些令人讨厌的原因,大多数人都喜欢使用“高级语言”(例如C),尽管这对人类来说可能看起来非常愚蠢(尽管我们知道计算机在设计上是愚蠢的),但指令集始终是正确的并非总是最好的选择,这就是为什么仍然有很多编译器的原因。

I can give you two more tips: 我可以再给您两个提示:

  1. you IDE must have a way to interleave assembler instructions with C code, and to single step within the assembler. 您的IDE必须有一种方法将汇编程序指令与C代码交织在一起,并在汇编程序内进行单步执行。 Try to find it out and explore it yourself 尝试找出并自己探索

  2. the IDE should also have a function to explore the memory of your program. IDE还应该具有探索程序内存的功能。 If you find that try to enter the 0x560 address and look were it will lead you. 如果您发现尝试输入0x560地址并查看是否会引导您。 It is very likely that that will be the entry point of your printf 这很有可能是您的printf的切入点

I hope that my answer will help you work it out, good luck 希望我的回答能帮助您解决问题,祝您好运

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

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