ARM汇编之APCS规则

本文详细解析了APCS规则下寄存器的使用规范,包括r0-r3作为函数参数传递的规则,以及r4-r11用于保存局部变量的规则。深入探讨了栈的使用规则及函数调用时参数的传递方式,同时提供了汇编调用C语言函数的具体实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

APCS规则简述
  1. 寄存器使用规则
    寄存器r0-r3用于函数调用过程中传递函数形参,各有一个别名 a1—a4,使用前后可以不用恢复原来的值
    R4-r11用于保存函数内部局部变量的值,每个函数使用前,必须要保存被调用函数的值,使用完毕,必须恢复原值。各有一个别名叫v1-v8.
//特殊寄存器说明
R10	sl	栈限制
R11	fp	桢指针
R12	ip	内部过程调用寄存器
R13	sp	栈指针
R14	lr	连接寄存器
R15	pc	程序计数器
  1. 栈的使用规则
//APCS规则规定,AMR的栈采用满减使用指令
Stmfd sp!,{}
Ldmfd sp!{}
Push{}
Pop{}

  1. 调用函数时参数的传递规则
    被调用的函数形参,如果小于等于四个,那么从左向右依次由r0-r3来传递参数
    如果被调用函数的形参大于四个,那么从左向右前四个依然由r0-r3传递,其余通过堆栈传递。
    函数的返回值被存入r0
汇编调用汇编函数
loop:
	mov r0,r1 //将r1的值放入r0
	add r1,r2;#32
	bl loop //调用后返回现场
汇编调用C语言函数

我们通过反汇编

arm-linux-gcc –g –mapsc arg.c 
arm-linux-gcc-objdump –Ds  arg

发现在处理函数的时候都都会有这些话,前三行和后两行,他就是对现场的布置,就是函数的跳转和返回

mov     ip, sp                  //IP=SP;保存SP
stmdb   sp!, {fp, ip, lr, pc}   //先对SP减4,再对fp,ip,lr,pc压栈。
sub     fp, ip, #4      ; 0x4   //fp=ip-4;此时fp指向栈里面的“fp”
bl       main 					//跳转到main函数

sub     sp, fp, #12     ; 0xc   //sp=fp-12;此时sp指向栈里面的lr
ldmia   sp, {fp, sp, pc}        //弹栈pc=lr,sp=ip,fp=fp。然后地址加4

纯汇编代码的编写
.text 关键字,用于声明代码段
.align 2 定义半字对齐,对齐代码
.global _start  声明全局变量.这个是程序入口声明,与链接脚本有关,链接脚本中将制定程序入口。
_start: 标号,定义程序入口。下面必须保存现场,所以需要使用5条指令

mov     ip, sp                  //IP=SP;保存SP
stmdb   sp!, {fp, ip, lr, pc}   //先对SP减4,再对fp,ip,lr,pc压栈。
sub     fp, ip, #4      ; 0x4   //fp=ip-4;此时fp指向栈里面的“fp”
bl       main 					//跳转到main函数

sub     sp, fp, #12     ; 0xc   //sp=fp-12;此时sp指向栈里面的lr
ldmia   sp, {fp, sp, pc}        //弹栈pc=lr,sp=ip,fp=fp。然后地址加4

纯汇编的编译
获取过程 arm-linux-gcc –c demo.S 编译为 .o 目标文件
Arm-linux-ld demo.o –Ttext=0x50000000 –o arm
然后用nm工具看看arm 发现入口地址被指定为50000000
但是此时生成的文件具有头信息,
File arm 查看文件信息。发现很多ASCII码,机器无法识别,需要去头。
Arm-linux-objcopy –O binary arm arm.bin  使用objcopy工具,去头。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值