考慮下面的C語言代碼:爲什麼gcc在arm FIQ中斷處理程序中保存r4?
extern void dummy(void);
void foo1(void) __attribute__((interrupt("IRQ")));
void foo2(void) __attribute__((interrupt("FIQ")));
void foo1() {
dummy();
return;
}
void foo2() {
dummy();
return;
}
通過臂gnueabi GCC產生的代碼基本上是這樣的:
foo1:
sub lr, lr, #4
stmfd sp!, {r0, r1, r2, r3, ip, lr}
bl dummy
ldmfd sp!, {r0, r1, r2, r3, ip, pc}^
foo2:
sub lr, lr, #4
stmfd sp!, {r0, r1, r2, r3, r4, lr}
bl dummy
ldmfd sp!, {r0, r1, r2, r3, r4, pc}^
爲foo1代碼不持有任何意外。 r0-r3
和ip
被保存,因爲虛擬的調用可能會改變它們的值。另外,在校正lr
之後,它最終被推入並彈出到pc中。這是相當標準的。
但是,foo2的代碼是令人驚訝的。不需要保存ip
的值,因爲它是一個銀行註冊。但是gcc保存r4
是令人驚訝的。
那麼爲什麼gcc保存r4?我沒有看到有任何理由這樣做,因爲虛擬電話不會破壞這個寄存器。
僅供參考https://github.com/gcc-mirror/gcc/blob/master/gcc/config/arm/arm.c#L18976 – auselen 2014-08-28 07:39:56
http://stackoverflow.com/q/25282466/1163019 – auselen 2014-08-28 07:40:59