I am starting to learn assembly (x86-64 in NASM on OSX), and am now exploring how functions look in it.
Most resources explaining how "calling conventions" work show examples along the lines of this:
// c code
MyFunction1(a, b);
// assembly code
main:
push a
push b
push rbp ; save frame pointer on stack
mov rsp, rbp ; save stack pointer in frame pointer
xor rax, rax ; set function return value to 0.
call _MyFunction
mov rbp, rsp ; restore stack pointer
pop rbp ; restore frame pointer
ret ; return to calling function
(I just made that up after combining several resources, so there are probably many problems with that, but that's outside the main question.).
The gist of what calling conventions like the cdecl calling convention, is that:
So, in hopes of getting some more practical experience of working with the stack and function calling conventions in assembly, I was hoping to see how existing C compilers converted function calls into assembly (gcc and clang, using this which is great). But, I am not seeing that calling convention pattern (which every resource I've seen so far has said is the way to do it)!
Check it out, here is a relatively complex bit of assembly code generated from some C:
https://gist.github.com/lancejpollard/a1d6a9b4820473ed8797
Looking through that C code, there are a couple levels of nested function calls. But the output assembly code doesn't show that push/pop stack pattern!
So the question is, are these compilers just optimizing the assembly so as to avoid doing that? (Because, that example C code, while having some nested functions, is still pretty simple so I imagine the compiler can precompute a lot of stuff). Or am I missing something?
In general:
static
and you are creating an object file) then the compiler has to respect the calling conventions (so that linking can work).For all other cases the compiler is free to completely ignore calling conventions and do whatever it thinks is more efficient (including passing parameters in registers and not using the stack or frame pointer, and also including inlining functions completely).
However: