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.
 
     
    