Я пытаюсь лучше понять компиляторы и сборку и в настоящее время пытаюсь понять, почему эта простая программа «Hello, World» изменяет стек и регистры% al перед вызовом printf.
Это сборка, сгенерированная gcc с отключенной оптимизацией (некоторые директивы компилятора были удалены):
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
leaq L_.str(%rip), %rdi
movl $0, -4(%rbp)
movb $0, %al
callq _printf
xorl %ecx, %ecx
movl %eax, -8(%rbp) ## 4-byte Spill
movl %ecx, %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
## -- End function
.section __TEXT,__cstring,cstring_literals
L_.str: ## @.str
.asciz "Hello, World!\n"
А вот (чрезвычайно простая) программа на C:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
Мне интересно, что конкретно происходит в двух строках, предшествующих инструкции "call _printf". Кажется, что часть стека обнуляется, а также регистр% al, но я не знаю почему.
Меня также смущает, почему регистр% ecx очищается и заполняется содержимым% eax, которое, я полагаю, является возвращаемым значением из printf перед возвратом.
Заранее спасибо за любую помощь.