2014-08-27 72 views
1

考慮下面的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-r3ip被保存,因爲虛擬的調用可能會改變它們的值。另外,在校正lr之後,它最終被推入並彈出到pc中。這是相當標準的。

但是,foo2的代碼是令人驚訝的。不需要保存ip的值,因爲它是一個銀行註冊。但是gcc保存r4是令人驚訝的。

那麼爲什麼gcc保存r4?我沒有看到有任何理由這樣做,因爲虛擬電話不會破壞這個寄存器。

+0

僅供參考https://github.com/gcc-mirror/gcc/blob/master/gcc/config/arm/arm.c#L18976 – auselen 2014-08-28 07:39:56

+0

http://stackoverflow.com/q/25282466/1163019 – auselen 2014-08-28 07:40:59

回答

1

我懷疑它是否確保EABI所需的8字節堆棧對齊。使用的實際寄存器無關緊要,可能是r12或其他任何內容 - 僅用於額外的4字節調整。

+0

那說得通。 – Sven 2014-08-27 17:03:20