(第一章)嵌入式linux之常用汇编指令

1.处理器内部数据传输指令

数据传输指令分为 一般寄存器间的数据传输或者 特殊寄存器与一般寄存器间的数据传输。
数据传输常用的指令有三个: MOV MRS MSR

 用法示例:

1 MOV 指令
MOV R0,R1 @将寄存器 R1 中的数据传递给 R0,即 R0=R1
MOV R0, #0X12 @将立即数 0X12 传递给 R0 寄存器,即 R0=0X12
2 MRS 指令
MRS R0, CPSR @将特殊寄存器 CPSR 里面的数据传递给 R0,即 R0=CPSR
3 MSR 指令
MSR CPSR, R0 @将 R0 中的数据复制到 CPSR 中,即 CPSR=R0

注:MRS 指令用于将特殊寄存器(CPSR SPSR)中的数据传递给通用寄存器,MSR 指令和 MRS 刚好相反,MSR 指令用来将普通寄存器的数据传递给特殊寄存器,也就是写特殊寄存器,写特殊寄存器只能使用 MSR.

我是这样记的:M开头就是传输指令,MOV最好记,MRS与MSR,R就是(READ)读取,强调读取操作,是读取特殊寄存器中的值。或者你可以认为MRS中R代表普通寄存器,S代表special特殊寄存器,而汇编都是反着读的。

2.存储器访问指令

ARM 不能直接访问存储器,比如 RAM 中的数据, I.MX6UL 中的寄存器就是 RAM 类型的,用汇编来配置 I.MX6UL 寄存器的时候需要借助存储器访问指令,一般先将要配置的值写入到Rx(x=0~12) 寄存器中,然后借助存储器访问指令将 Rx 中的数据写入到 I.MX6UL 寄存器中。读取 I.MX6UL 寄存器也是一样的,只是过程相反。常用的存储器访问指令有两种:LDR 和STR。

  用法示例:

1 LDR 指令
LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1, [R0] @读取地址 0X0209C004 中的数据到 R1 寄存器中
2 STR 指令
LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1, =0X20000002 @R1 保存要写入到寄存器的值,即 R1=0X20000002
STR R1, [R0] @将 R1 中的值写入到 R0 中所保存的地址中

注:LDR 和 STR 都是按照字进行读取和写入的,也就是操作的 32 位数据,如果要按照字节、 半字进行操作的话可以在指令“LDR”后面加上 B H,比如按字节操作的指令就是 LDRB 和STRB,按半字操作的指令就是 LDRH STRH

我是这样记的:LDR和STR指令的作用我其实感觉有点抽象,因为一开始说的MOV,MSR,MRS指令其实就和他们作用貌似完全一致,区别就是LDR与STR是用于读取存储器中的数据的(RAM类寄存器)其实我有点蒙,在我印象里RAM和ROM类型存储介质的区别一个就是掉电丢失与掉电不丢失,另外寄存器加了[]貌似就如C中的取地址符号,这些也是要注意一下的,而STR指令也是唯一一个从右往左读的汇编指令。

3.压栈和出栈指令

A 函数中调用 B 函数,当 B 函数执行完以后再回到 A 函数继续执行要想再跳回 A 函数以后代码能够接着正常运行,那就必须在跳到 B 函数之前将当前处理器状态保存起来

B 函数执行完成以后再用前面保存的寄存器值恢复 R0~R15 即可。保存 R0~R15 寄存器的操作就叫做现场保护,恢复 R0~R15 寄存器的操作就叫做恢复现场。
在进行现场保护的时候需要进行压栈 ( 入栈 ) 操作,恢复现场就要进行出栈操作。

PUSH {R0~R3, R12} @将 R0~R3 和 R12 压栈
PUSH {LR} @将 LR 进行压栈

处理器的堆栈是向下增长的, 栈区示意图:汇编从右往左读,入栈顺序为R12,R3,R2,R1,R0,LR

POP {LR} @先恢复 LR 
POP {R0~R3,R12} @在恢复 R0~R3,R12
出栈的就是从栈顶,也就是 SP 当前执行的位置开始,地址依次减小来提取堆栈中的数据到要恢复的寄存器列表中。
我是这样记的:这个就没什么好说了,不懂栈数据类型的建议先补一下栈数据类型,只有PUSH和POP两个指令,比较简单。

4.跳转指令

有多种跳转操作,一般常用的还是 B BL BX。
1 B 指令
_start: 
ldr sp,=0X80200000 @设置栈指针
b main @跳转到 main 函数
2 BL 指令
push {r0, r1} @保存 r0,r1
cps #0x13 @进入 SVC 模式,允许其他中断再次进去
bl system_irqhandler @加载 C 语言中断处理函数到 r2 寄存器中
cps #0x12 @进入 IRQ 模式
pop {r0, r1} 
str r0, [r1, #0X10] @中断执行完成,写 EOIR

注:BL 指令相比 B 指令,在跳转之前会在寄存器 LR(R14)中保存当前 PC 寄存器值,所以可以通过将 LR 寄存器中的值重新加载到 PC 中来继续从跳转之前的代码处运行,这是子程序调用一个基本但常用的手段。

5.算术运算指令

汇编中也可以进行算术运算, 比如加减乘除,常用的运算指令用法如下

主要讲解了一些最常用的指令,还有很多不常用的指令没有讲解 , 但是 够我 们后 续学习用了,要想详细的学习 ARM 的 所有 指令 请参 考《 ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf》和《 ARM Cortex-A(armV7) 编程手册 V4.0.pdf 》这两份文档。
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值