GCC compiled assembly
I am trying to learn assembly language by example, or compiling simple C files with GCC using the -S option, intel syntax, and CFI calls disabled (every other free way is extremely confusing
My C file is literally just int main() {return 0;}
, but GCC spits out this:
.file "simpleCTest.c"
.intel_syntax noprefix
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
push ebp
mov ebp, esp
and esp, -16
call ___main
mov eax, 0
leave
ret
.ident "GCC: (GNU) 5.3.0"
My real question is why does the main function have any processor instructions ( push edp
, mov edp, esp
, etc)? Are these even necessary (I guess it would be a way of data management to prepare/shut down programs, but I'm not sure)? Why doesn't it just issue a ret
statement after the main function? Also why are there TWO main functions (_main & ___main)?
To sum it up, why is it not just like this?
.def _main
_main:
mov eax, 0 ;(for return integer)
ret
GCC spits out this
This would probably be a bit clearer if you actually had your main function do some things, oddly enough, including calling another function.
Your compiled code is setting up a frame by which to reference its stack variables with the first opcode, mov ebp,esp. This would be used if you had variables that could be referred to with ebp and a constant, for instance. Then, it is aligning the stack to a multiple of 16 bytes with the AND instruction- that is, it is saying it will not use from 0 to 15 bytes of the provided stack, such that [esp] is aligned to a multiple of 16 bytes. This would be important because of the calling conventions in use.
The ending opcode leave copies the backed up base pointer over the current state of the stack pointer, and then restores the original base pointer with pop.
My real question is why does the main function have any processor instructions
It's setting stuff up for things that you aren't doing (but that nontrivial programs would do), and is not making the most optimized "return 0" program that it could. By having a base pointer that is mostly a backup of the original stack pointer, the program is free to refer to local variables as an offset plus the base pointer (including implied stuff you aren't using like the argument count, the pointer to the pointers to argument listing, and the pointer to the environment), and by having a stack pointer that is a multiple of 16, the program is free to make calls to functions according to its calling standard.
链接地址: http://www.djcxy.com/p/86796.html上一篇: 在Objective中初始化静态变量
下一篇: GCC编译汇编