寄存器使用规则学习小结

r0-r3:就是保存子程序的操作数。子程序返回时需要恢复这些寄存器值么?不!

          如果参数多于4个,就需要用栈来保存了。r12就是用来保存栈指针的,子程序返回时也不需要恢复r12.

          r0经常被用做子程序返回值

r4-r11:这8个寄存器用来保存子程序的局部变量,返回时需要恢复。

r13: sp,堆栈指针,sp在进入子程序和退出子程序时要相等。

r14:链接寄存器 lr。保存子程序的返回地址,如果子程序中保存了返回地址,可以用做其它用途,但子程序返回时需要恢复。

r15: pc 程序寄存器。

在中断中,所有寄存器都必须保护,编译器会自动保护r4-r11


举个例子:

#include <stdio.h>

extern int strcopy(char *dst, const char *src);

int main()

{

    int ret=0;

    const char *src = "Hello world!";

    char dst[] = "World Hello!";

    printf("dst string is %s and src string is %s\n", dst, src);

    ret = strcopy(dst, src);

    printf("After copying %d chars and now dst string is %s\n", ret, dst);

    return 0;

}

strcopy 子程序是汇编,要用extern修饰,.就是 .global, strcopy.S是通过寄存器r0和r1引用它们的。

strcopy.S 的内容

.setction .text
.align 2
.global strcopy
strcopy:
/*let r4 as a counter and return*/
push {r4}
mov r4, #0

1:
  ldrb r2, [r1], #1  @load 完,地址自增1
  strb r2, [r0], #1
  cmp r2, #0
  add r4, r4, #1
  bne 1b

  mov r0, r4  @as a return value
  pop {r4}

  mov pc, lr @continue  to exec next instruction
  

r2在子程序中使用了,无需保存; r4是计数器,统计复制字符的个数,程序一开始就入栈了,结束时弹出,统计值通过r0返回。

r0,  r1是子程序的参数

lr 是c函数调用子程序时,保存的函数需要执行的下一个地址,子函数返回时要赋给pc

这个函数的编译:

#arm-linux-gcc -c hello.c -o hello.o
#arm-linux-as -c strcopy.S strcopy.o
#arm-linux-ld hello.o strcpy.o -o hello

若找不到动态链接库,只需要使用一个:

arm-linux-gcc hello.o strcpy.o -o hello -v


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值