1. r0,r1,r2,r3,在調用函數時,用來存放前4個函數參數和返回值,r4-r11,r14,在調用函數時必須保存這些寄存器到堆棧當中。若是函數的參數多於4個,則多餘參數存放在堆棧當中,即sp,sp+4,sp+8,…依次類推。ide
2. 函數內部通用的入棧出棧代碼能夠爲:函數
STMFD sp!,{r4-r11,lr}spa
// body of ASM codecode
LDMFD sp!,{r4-r11,pc}it
若是函數並無用到那麼多的寄存器,則沒有必要把全部的寄存器入棧。若是函數要調用子函數,則r0,r1,r2,r3,r12,r14這些寄存器裏面值將被改變,必須當心處理這些寄存器,一種可行的方法是,修改被調用子函數的入棧出棧代碼爲:class
STMFD sp!,{r0-r12,lr}變量
// body of ASM code方法
LDMFD sp!,{r0-r12,pc}im
3. 若是函數內部變量太多,這時候要考慮使用堆棧,這是入棧出棧代碼能夠爲:margin
STMFD sp!,{r4-r11,lr}
SUB sp, sp, #stacksize
// body of ASM code
ADD sp, sp, #stacksize
LDMFD sp!,{r4-r11,pc}
4. 若是函數的參數多於4個,則函數內部的參數在堆棧中的位置依入棧出棧代碼而定:
STMFD sp!,{r4-r11,lr}
LDR r4,[sp,#36] //第5個參數在堆棧中的位置
LDR r5,[sp,#40] //第6個參數在堆棧中的位置
// ……
// body of ASM code
LDMFD sp!,{r4-r11,pc}
5. 若是第5個參數是要傳遞地址,函數調用完之後要使用以前傳進去的第5個參數,則要預留更多的堆棧空間。可參考下面代碼:
//other C code
butterfly32a_16(x2m[0], x2m[1], *ptr1--, tmpSineTable8m, &rx, &ix);
//other C code
這個C函數總共有6個參數,在調用以前要預留4個堆棧單元。代碼以下:
sp_0 EQU 0
sp_1 EQU sp_0 + 4
var_rx EQU sp_1 + 4
var_ix EQU var_rx+4
stacksize EQU var_ix+4
STMFD sp!,{r4-r11,lr}
SUB sp, sp, #stacksize
// other ASM code
ADD r4, sp, #var_rx
ADD r5, sp,# var_ix
STR r4, [sp,#sp_0]
STR r5, [sp,#sp_1]
// assume the r0,r1,r2,r3 are prepared well
BL butterfly32a_16
LDR r4, [sp, #var_rx] //r4 is the value of rx
LDR r5, [sp, #var_ix] //r5 is the value of ix
// other ASM code
ADD sp, sp, #stacksize
LDMFD sp!,{r4-r11,pc}