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.
-O3or-O2to get just the interesting part. How to remove "noise" from GCC/clang assembly output?-O1, better-O2so the compiler generates reasonable code.