Я пытаюсь изучить ассемблер и есть пара инструкций, назначение которых мне не совсем понятно.
код C
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Argument One - %s\n", argv[1]);
return 0;
}
Монтаж
.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
Почему пространство выделяется для 32 байтов, когда нет локальных переменных? Я считаю, что argc и argv сохраняются в регистрах edi и rsi соответственно. Если это так, что они могут быть перемещены в стек, разве это не потребует только 12 байтов?
Q2. lea rax, [rip + L_.str] и mov rdi, rax
Правильно ли я понимаю, что L_.str имеет адрес строки "" Первый аргумент -% s \ n "? Из того, что я понял, printf получает доступ к этой строке через регистр rdi. Итак, почему не работает ли инструкция mov rdi, L_.str ?
Q3. mov dword ptr [rbp - 4], 0
Почему ноль помещается в стек?
Q4. mov dword ptr [rbp - 8], edi и mov qword ptr [rbp - 16], rsi
Я полагаю, что эти инструкции должны получить argc и argv в стек. Чисто ли принято использовать edi и rsi?
В5. mov dword ptr [rbp - 20], eax
Понятия не имею, что это делает.