Рассмотрим следующий код:
#include <stdio.h>
void foo() {
printf("Hello world\n");
}
void bar() {
printf("Hello world");
}
Сборка, созданная обеими этими двумя функциями:
.LC0:
.string "Hello world"
foo():
mov edi, OFFSET FLAT:.LC0
jmp puts
bar():
mov edi, OFFSET FLAT:.LC0
xor eax, eax
jmp printf
Теперь я знаю разницу между put и printf , но я нахожу это довольно интересным, поскольку g cc может проанализировать const char * и выяснить, вызывать ли printf или put.
Другая интересная вещь заключается в том, что в bar
компилятор обнуляет регистр возврата (eax
), даже если это функция void
. Почему он сделал это там, а не в foo
?
Правильно ли я предположил, что компилятор «изучил мою строку», или есть другое объяснение этого?