ARM assembly: Lesson 10

今天,我们来看一下基于ARM汇编,如何实现函数的调用。

基础知识

在ARM汇编中,函数的前四个参数存放于 R0~R3寄存器中, 剩余的参数存放于栈中,返回值存放于r0。在栈中存放数值,可以避免在调用过程中,数据的丢失,因为寄存器有限,并且经常被更新。

Function names in C are like labels in assembly.

The PC(program counter register) holds the address of the currently executing instruction.

函数实现

函数原型

首先,通常函数的C代码,我们基本理解我们需要干嘛------实现加法。

复制代码
int add_nums(int num1, int num2)
{
return num1 + num2;
}

int main()
{
    add_nums(1,2};
    return 0;
}

汇编实现

LR (Link Register) 用于存放函数调用后,接下来的指令的地址。

复制代码
.global _start
_start:
	
	mov r0, #1  //arg1
	mov r1,	#2	//arg2
	
	push {r0, r1}
	bl add_nums
	mov r2, r0
	pop {r0,r1}
	
add_nums:
	add r0,r0,r1
	bx lr

将r0, r1 存入栈中。这里可以观察到,sp指向的位置从0变成了一个很大的数字,在内存中查看对应的地址,可以看到,就是1,2!

在此前,我们提到了b可以作为无条件分支的关键词,此外,还有bl(branch with link)。bl除了可以进行分支之外,还可以存储PC的状态,保证在函数调用之后,回到调用之前的状态(PC地址)。

然后,通过step into,我们进入add_nums label,然后,对应的可以看到r0被更新为3. 通过bx指令,我们可以访问lr寄存器中的地址,对应的就是 mov r2, r0.

然后通过pop,我们基于栈中存储的元素更新了r0,r1,r0从3变成了1。可以观察到sp指向的地址变为0,可以理解为栈为空,但是,此前的地址中的数字并没有改变,还是1和2.

Take Away

bx lr指令用于访问存放于**Link Register (LR)**的地址。

push 和pop用于将数字存放于栈中,或者从栈中获取。

复制代码
PUSH {R0, R1}  // Push R0 and R1 onto the stack
相关推荐
社会零时工8 小时前
机械臂末端2D相机自动对焦应用
arm开发·机器学习
陌上花开缓缓归以20 小时前
W25N01KVZEIR flash烧写
arm开发
济6172 天前
ARM Linux 驱动开发篇----字符设备驱动开发(4)--- 编写chrdevbase 字符设备驱动开发实验--- Ubuntu20.04
linux·arm开发·驱动开发
代码游侠2 天前
学习笔记——I2C子系统
linux·arm开发·驱动开发·单片机·嵌入式硬件
陌上花开缓缓归以3 天前
mips架构uboot 启动流程分析
arm开发·架构
陌上花开缓缓归以3 天前
ddr专题分析
arm开发
电脑小白技术3 天前
arm架构能装windows吗?arm架构安装Windows两种方法
arm开发·windows·架构·arm架构能装windows吗
ONLYOFFICE3 天前
如何在 openSUSE 16 ARM 上安装 ONLYOFFICE 桌面编辑器
arm开发·编辑器
梁洪飞3 天前
uboot spl学习
linux·arm开发·嵌入式硬件·arm
戏舟的嵌入式开源笔记3 天前
Arm2D使用教程(四):借助片外Flash放置图片资源
arm开发·stm32·arm2d