Почему LLVM добавляет две дополнительные инструкции для одной и той же программы?
Я компилирую эту программу на языке Си и сравниваю сгенерированный ассемблерный код:
int main(){ return 0; }
GCC дает эту основную функцию (cc hello.c -S
):
_main:
LFB2:
pushq %rbp
LCFI0:
movq %rsp, %rbp
LCFI1:
movl $0, %eax
leave
ret
LLVM дает эту основную функцию (clang hello.c -S
):
_main:
Leh_func_begin0:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl $0, %eax
movl $0, -4(%rbp)
popq %rbp
ret
Leh_func_end0:
Для чего нужны movl $0, -4(%rbp)
и popq %rbp
? Двигать что-то на стопке и сразу же после этого класть это кажется мне бесполезным.
3 ответа:
На самом деле, они сравнимы. Отпуск-это инструкция высокого уровня:
Из руководства Intel:
16-bit: C9 LEAVE A Valid Valid Set SP to BP, then pop BP. 32-bit: C9 LEAVE A N.E. Valid Set ESP to EBP, then pop EBP. 64-bit: C9 LEAVE A Valid N.E. Set RSP to RBP, then pop RBP.
В принципе, отпуск эквивалентен
movq %rbp, %rsp popq %rbp