ITPub博客

首页 > 应用开发 > > C语言的ARM实现(五)函数

C语言的ARM实现(五)函数

作者:zhjjj 时间:2019-08-28 15:52:01 0 删除 编辑
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)。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/717/viewspace-3138159/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-04-12

  • 博文量
    231
  • 访问量
    1888