Ho provato a scrivere un semplice codice di test simili (main.c):Perché ARM gcc inserisce il registro r3 e lr nello stack all'inizio di una funzione?
main.c
void test(){
}
void main(){
test();
}
Poi usato braccio-non-eabi-gcc per compilare e objdump per ottenere il codice assembly:
arm-none-eabi-gcc -g -fno-defer-pop -fomit-frame-pointer -c main.c
arm-none-eabi-objdump -S main.o > output
Il codice assembly spinge i registri r3 e lr, anche la funzione non ha fatto nulla.
La mia domanda è perché arm gcc sceglie di spingere r3 nello stack, anche la funzione test() non la usa mai? Gcc sceglie casualmente 1 registro per premere? Se è per il requisito di allineamento pila (8 byte per ARM), perché non sottrarre semplicemente la sp? Grazie.
================== Aggiornamento =====================
@KemyLand per la risposta, ho un altro esempio: il codice sorgente è:
void test1(){
}
void test(int i){
test1();
}
void main(){
test(1);
}
io uso lo stesso comando di compilazione sopra, quindi il seguente assemblea:
main.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <test1>:
void test1(){
}
0: e12fff1e bx lr
00000004 <test>:
void test(int i){
4: e52de004 push {lr} ; (str lr, [sp, #-4]!)
8: e24dd00c sub sp, sp, #12
c: e58d0004 str r0, [sp, #4]
test1();
10: ebfffffe bl 0 <test1>
}
14: e28dd00c add sp, sp, #12
18: e49de004 pop {lr} ; (ldr lr, [sp], #4)
1c: e12fff1e bx lr
00000020 <main>:
void main(){
20: e92d4008 push {r3, lr}
test(1);
24: e3a00001 mov r0, #1
28: ebfffffe bl 4 <test>
}
2c: e8bd4008 pop {r3, lr}
30: e12fff1e bx lr
Se spinta {r3, lr} nel primo esempio serve per usare meno istruzioni, perché in questa funzione test(), il comp iler non ha usato solo un'istruzione?
push {r0, lr}
Si usa 3 istruzioni invece di 1.
push {lr}
sub sp, sp #12
str r0, [sp, #4]
proposito, perché sub sp con 12, la pila è di 8 byte allineato, può semplicemente sub con 4 giusto?
possibile duplicato di [Perché il puntatore dello stack è stato spostato di 4 byte maggiore della dimensione del frame dello stack durante la compilazione con arm-linux-gnueabi-gcc?] (http://stackoverflow.com/questions/22279911/why-is-the-stack-pointer-moved-down-4-bytes-greater-than-the-stack-frame-size-wh) – auselen
e un altro possibile duplicato di http://stackoverflow.com/questions/16120123/arm-why-do-i-need-to-push-pop-two-registers-at-function-calls – auselen
per assicurare l'allineamento dello stack, è stato chiesto e ha risposto qui un numero di volte –