0

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. The C code:

#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)?

9
  • 5
    If your class is in Assembly programming, reading compiler generated code is not going to be of help. It's likely to be detriment in this stage of your education. Commented Jan 17, 2018 at 12:11
  • 5
    you can try using gcc -c -S -fverbose-asm file.c - that should generate file.s with commented ASM Commented Jan 17, 2018 at 12:11
  • 1
    It helps to single-step thropugh the assembler with your debugger, taking note of the actions on registers, memory etc. Commented Jan 17, 2018 at 12:12
  • 1
    @StoryTeller My upcoming exam will have questions like "Rewrite the above X86-assembler program in C", so I thought by practicing the other way around I could benifit. Commented Jan 17, 2018 at 12:15
  • 3
    You should also check optimized output of compiler, your current assembly is unoptimized -O0 updating stack frame and local variables after each line of source to make debugging in C source "per line" possible, the machine code generated without that feature will be considerably different (also much shorter, and probably easier to understand from the point of pure assembly ... and a bit harder to rewrite back into C source, at that point you must basically do asm -> algorithm -> write C from scratch, while the unoptimized code can be reconstructed almost literally by asm->C back-translation). Commented Jan 17, 2018 at 12:31

2 Answers 2

5
 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) 
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! So the first line is because arg[1] is not in the stackframe, so we have to move it into another register fist, before we can move it into an address in the stackframe?
yes, because x86 and x64 don't have general memory to memory instruction (some exists but not for general use)
You don't have to copy it, it's just unoptimized code. Notice it's writing rax into memory, then reloading it and then transferring to rdi. Those 3 instructions can be replaced by a single mov 0x8(%rax), %rdi
2

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. 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. 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.

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. Try to find it out and explore it yourself

  2. the IDE should also have a function to explore the memory of your program. If you find that try to enter the 0x560 address and look were it will lead you. It is very likely that that will be the entry point of your printf

I hope that my answer will help you work it out, good luck

2 Comments

It was unclear to me why the mov %rax,%rdi was there, thank you :)
OP compiled without optimizations. It's fairly normal to see really weird stuff when disabling optimizations. I recommend to compile with at least -O1 to get the most basic optimizations in.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.