I am trying to learn assembly and there a couple of instructions whose purpose I do not fully understand.
C code
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Argument One - %s\n", argv[1]);
return 0;
}
Assembly
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 14
.intel_syntax noprefix
.globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
## %bb.0:
push rbp
mov rbp, rsp
sub rsp, 32
lea rax, [rip + L_.str]
mov dword ptr [rbp - 4], 0
mov dword ptr [rbp - 8], edi
mov qword ptr [rbp - 16], rsi
mov rsi, qword ptr [rbp - 16]
mov rsi, qword ptr [rsi + 8]
mov rdi, rax
mov al, 0
call _printf
xor ecx, ecx
mov dword ptr [rbp - 20], eax ## 4-byte Spill
mov eax, ecx
add rsp, 32
pop rbp
ret
## -- End function
.section __TEXT,__cstring,cstring_literals
L_.str: ## @.str
.asciz "Argument One - %s\n"
.subsections_via_symbols
Q1. sub rsp, 32
Why is space allocated for 32 bytes when there are no local variables? I believe argc and argv are saved in the registers edi and rsi respectively. If its so that they can be moved onto the stack, wouldn't that require only 12 bytes?
Q2. lea rax, [rip + L_.str] and mov rdi, rax
Am I correct in understanding that L_.str has the address of the string ""Argument One - %s\n"? From what I've understood, printf gets access to this string through the register rdi. So, why doesn't the instruction mov rdi, L_.str work instead?
Q3. mov dword ptr [rbp - 4], 0
Why is zero being pushed onto the stack?
Q4. mov dword ptr [rbp - 8], edi and mov qword ptr [rbp - 16], rsi
I believe these instruction are to get argc and argv onto the stack. Is it pure convention to use edi and rsi?
Q5. mov dword ptr [rbp - 20], eax
I haven't a clue what this does.
-O3
or-O2
to get just the interesting part. How to remove "noise" from GCC/clang assembly output? – Peter Cordes-O1
, better-O2
so the compiler generates reasonable code. – fuz