Saturday, May 23, 2015

gcc convert c to assembly

Take this c program that does nothing but exit.

#include<stdlib.h>
void main(){
  exit(0);
}



Let's say you run this command to build...
  gcc -S -masm=intel -static exit.c

Then if you view your directory you'll see you have an assembly file (exit.s)...
ls -l
-rw-rw-r-- 1 user user 140 May 20 12:02 exit.c
-rw-rw-r-- 1 user user 391 May 20 12:33 exit.s


Here is the output of the assembly file.

  .file "exit.c"
  .intel_syntax noprefix
  .text
  .globl main
  .type main, @function
main:
.LFB2:
  .cfi_startproc
  push ebp
  .cfi_def_cfa_offset 8
  .cfi_offset 5, -8
  mov ebp, esp
  .cfi_def_cfa_register 5
  and esp, -16
  sub esp, 16
  mov DWORD PTR [esp], 0
  call exit
  .cfi_endproc
.LFE2:
  .size main, .-main
  .ident "GCC: (Ubuntu xxxxx) xxxxx"
  .section .note.GNU-stack,"",@progbits


The .file tells assembly that we're starting a new file with this name.

The .intel_syntax noprefix tells assembly we're using intel version, and we are not going to prefix registers with a % symbol

The .text tells assembly that the code section is now starting.

The .globl main tells assembly that main is a symbol that can be used outside this file. That is needed for the operating system to make the initial call to start this program.

The .type main, @function is used in conjunction with the previous directive to tell the outside linker that main is a function

The main: creates a label called main, which is what we just defined in the previous 2 directives as an externally accessible function

The LFB2: is an auto-generated label by the compiler that likely stands for LABEL FUNCTION BEGIN #2, and is generally seen prior to every function.

The .cfi_starproc is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

The push ebp is setting up for your function call by saving the Base Pointer on the stack so you could restore it at the end of the function (of course this isn't used/necessary in this instance since we'll never return from this function as it's calling the exit syscall).

The .cfi_def_cfa_offset 8 is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

The .cfi_offset 5, -8 is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

The mov ebp, esp is also setting up for your function call by setting the new Base Pointer to the old Stack Pointer (basically saving off the previous stack for later use and starting a new stack for this scope).

The .cfi_def_cfa_register 5 is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

The and esp, -16 is essentially the same as and esp, 11111111 11111111 11111111 11110000. Removing last 4 bits means rounding down to 16 byte boundary.

The sub esp, 16 is allocating 16 bytes for local variables.

The mov DWORD PTR [esp], 0 is saving the value 0 to the stack (basically passing 0 as a parameter to the next function).

The call exit is the call to the syscall that exits with return code 0 (our parameter) to the operating system.

The .cfi_endproc is an auto-generated directive that the assembler will use during error handling to unwind an the stack.

The LFE2: is an auto-generated label by the compiler that likely stands for LABEL FUNCTION END #2, and is generally seen at the end of every function.

The .size main, .-main tells the assembler to compute the size of symbol main to be the difference between the label main and the current position in the file

The .ident "GCC: (Ubuntu xxxxx) xxxxx" identifies which version of the compiler generated this assembly.

The .section .note.GNU-stack,"",@progbits is where gcc (the compiler we used) specific stack options are specified.



Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.

No comments:

Post a Comment