-
int son(int a, int b)
-
{
-
int c = 0;
-
-
c = a + 2*b; //son函数执行一个相加操作
-
-
return c;
-
}
-
-
int main(int a)
-
{
-
int i = 1, j = 0;
-
-
j = son(a,i);
-
-
return j;
-
}
arm-linux-gcc -O1 call.c -S
汇编:
son:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
add
r0, r0, r1, asl #1
bx
lr
.size
son, .-son
.align
2
.global
main
.type
main, %function
main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
stmfd sp!, {r4, lr} //把r4和lr寄存器压栈
mov
r1, #1
bl
son
ldmfd sp!, {r4, lr} ////把r4和lr寄存器恢复
bx
lr
.size
main, .-main
.ident
"GCC: (ctng-1.6.1) 4.4.3"
.section
.note.GNU-stack,"",%progbits
==================
对
LDMFD和STMFD的理解
ARM里面的堆栈是满递减(FULL DESCENDING)的。SP指向最后一个入栈的数据,SP的地址由高向低生长。对于LDM和STM指令来说,编号小的寄存器对应堆栈中的低地址。
STMFD的寻址方式是事先递减方式(Decrease Before)。内存地址可以用下面的式子表示:
start_address=SP-(Number of register *4)
end_address=SP-4
举例来说:STMFD SP!,{R1-R7,LR} //SP=0x48000060
入栈后各寄存器存放的地址如下图所示:
SP后面的!表示SP=SP-(Number of registers *4),在这里入栈后SP指向R1寄存器入栈的地址。
LDMFD的寻址方式是事后递增方式(Increase After)。内存地址可以用下面的式子表示:
start_address=SP
end_address=SP+(number of registers*4)-4
举例来说:LDMFD SP!,{R1-R7,LR} //紧跟上例,SP=0x48000040
根据编号小的寄存器对应低地址的原则,0x48000040地址处的值出栈给R1寄存器,0x48000044地址处的值出栈赋给R2寄存器,依次类推。正好与STMFD一一对应。
SP后面的!表示要更新SP的值。SP=SP+(number of registers*4)。
阅读(2668) | 评论(0) | 转发(0) |