B Label, BL Label 指令

B Label, BL Label

跳转到标号Label 处,B跳转指令的跳转范围大小为[0,32MB], 可以往前跳,也可以往后条,无条件跳转指令B主要用在循环,分之结构的汇编程序中,使用示例如下。

CMP R2, #0

REQ label 若R2 = 0,则跳转到label处。

label:

....

2 BL label

BL跳转指令表示带链接的跳转,在跳转之前,BL指令会先将当前指令的下一条指令地址(即返回地址)保存到LR寄存器中,然后跳转到label处执行,BL指令一半用在函数调用的场合,主函数在跳转到自函数执行之前,会先将返回地址,即当前跳转指令的吓一条指令地址保存到LR寄存器中,自函数执行结束后,LR寄存器中的地址将被赋值给PC,处理器就可以返回到原来的主函数中继续运行了。

3 BX Rm

BX 表示带状态切换的跳转,Rm寄存器中保存的是跳转地址,要跳转的目标地址处可能是ARM指令,也可能是Thumb指令,处理器根据Rm[0]位决定是切换到ARM状态还是切换到Thumb状态。

0 表示目标地址处是ARM指令,在跳转之前要先切换到Thumb状态。

1 表示目标地址处是Thumb指令,在跳转之前要先切换的跳转,使用方法和上面相同。不再赘述。

3.3 ARM寻址方式

ARM属于RISC体系结构,一个ARM汇编程序中的大部分汇编指令,基本上都和数据传输有关,在内存一寄存器,内存一内存,寄存器一寄存器之间来回传输数据。不通的ARM指令又有不同的寻址方式,比较常见的寻址方式有寄存器寻址,立即寻址,寄存器偏移寻址,寄存器间接寻址,基止寻址,多寄存器寻址,相对寻址等。

3.3.1 寄存器寻址

寄存器寻址比较简单,操作数保存在寄存器中,通过寄存器名就可以直接对寄存器中的数据进行读写。

MOV R1, R2 将寄存器R2中的值传递到R1

ADD R1, R2, R3; R1 = R2 + R3

3.3.2 立即数殉职

在立即数旬之中,ARM指令中的操作数为一个常数,立即书以#

为前缀,0x前缀表示该立即数为十六进制,不加前缀默认是十进制。

ADD R1, R1, #1 将R1寄存器中的值加1,并将结果保存到R1中。

MOV R1, #0xff 将十六进制常熟0xff 写到R1寄存器中

MOV R1, #12 将十进制常熟12放到R1寄存器中

ADD R1,R1,#16 R1 = R1 + 16

3.3.3 寄存器偏移寻址

寄存器偏移寻址可以看作寄存器寻址的一种特特例,通过第二个操作数operand2 的灵活配置,我们可以将第二个操作数做各种左移和右移操作,作为新的操作数使用。

MOV R2,R1,L5L, #3

ADD R3, R2, R1, L5L, #3

ADD R3, R2, R1, L5L, R0

常见的移位操作有逻辑移位和算数移位,两者的区别是,逻辑移位无论是左移还是右移,空缺的一律补0,而算数移位则不同,左移补0,右移补符号位。

3.3.4 寄存器间接寻址

寄存器间接寻址主要用来在内存和寄存器之间传递数据,寄存器中保存的是数据在内存中的存储地址,我们通过这个地址就可以在寄存器和内存之间传输数据,C预研中的指针操作,在汇编层次其实就是使用寄存器间接寻址实现的,寄存器间接寻址的使用示例以及说明如下所示。

LDR R1,[R2] 将R2中的值作为地址,取该内存地址上的数据,保存到R1

STR R1, [R2] 将R2中的值作为地址,将R1寄存器的值写入该内存地址。

3.3.5 基址寻址

基址殉职其实也属于寄存器间接寻址。两者的不同之处在于,基址寻址将寄存器中国呢的地址与一个偏移量相加,生成一个新地址,然后基于这个新地址去访问内存。

LDR R1, [FP,#2] 将FP中的值加2作为新的地址,取改地址上的值保存到R1

LDR R1, [FP, #2]

LDR R1,[Fp, R0] 取FP + R0位置的值存入R1

STR R1, [FP, #-2] 将R1存入FP - 2地址位置。

基址寻址一般用在查表,数据访问,函数的栈帧管理等场合,根据偏移的正负,基址寻址又可以分为向前索引寻址和向后索引殉职,如上面的第一条和第三条指令,就是向后缩阴寻址,而第6条指令则为向前索引寻址。

3.3.6 多寄存器寻址

STM/LDM 指令就属于多寄存器寻址,一次可以传输多个寄存器的值

LDMIA SP!, {R0-R2, R14} 将内存栈中的数据依次弹出到R14, R2,R1,R0

STMDB SP!, {R0-R2,R14} 将R0,R1,R2,R14依次压入栈

STMFD SP!,

在多寄存器寻址中,用大括号括起来的就是寄存器列表,寄存器之间用逗号隔开,如果是连续的寄存器,还可以使用连续符号连接,如R0R3,就表示R0,R1,R2这4个寄存器,。

LDM/STM指令一半和IA,IB,DA,DB组合使用,分别表示Increase After, Increase Before, Decrease After Decrease Before

ARM没有专门的入栈和出栈指令,ARM中的栈操作其实就是通过上面所讲的STM/LDM指令和栈指针SP配合操作完成的,栈一半可以分为以下四类

递增栈A 入栈时,SP栈指针从弟弟址往高地址方向增长。

递减栈D 入栈时,SP栈指针从高地址往低地址方向增长

满栈F,SP栈指针总是指向栈顶元素。

空栈E,SP栈指针总是指向栈顶元素。

空栈E,SP栈指针总是指向栈顶元素的下一个空闲的存储单元。

ARM默认使用满递减堆栈,通过STMFD/LDMFD指令配对使用,完成堆栈的入栈和出栈操作,ARM中的PUSH和POP指令其实就是LDM/STM的同义词。

相关推荐
海滩游侠1 天前
ARM assembly: Lesson 10
arm开发
Eternal-Student1 天前
arm-伪指令
arm开发
Eternal-Student1 天前
everyday_question dq20240731
开发语言·arm开发·php
Tlog嵌入式2 天前
蓝桥杯【物联网】零基础到国奖之路:十六. 扩展模块之矩阵按键
arm开发·stm32·单片机·mcu·物联网·蓝桥杯·iot
Q8343158192 天前
华为 海思22AP10(SS524)H.265 编解码处理器用户指南
arm开发·人工智能·嵌入式硬件·音视频·硬件工程·h.265·视频编解码
星羽空间2 天前
win11下 keil报错Cannot load driver ‘D:\Keil_v5\ARM\Segger\JL2CM3.dll‘
arm开发·keil
日晨难再3 天前
AMBA:APB的历史(从APB1到APB5)
arm开发·arm·硬件工程·fpga·数字ic
Tlog嵌入式3 天前
蓝桥杯【物联网】零基础到国奖之路:十八. 扩展模块之光敏和AS312
arm开发·stm32·单片机·mcu·物联网·蓝桥杯·iot
汽车电子助手4 天前
【STM32开发环境搭建】-4-在STM32CubeMX中新增Keil(MDK-ARM) 5的工程目录(包含指定路径的C和H文件)
c语言·arm开发·stm32·stm32cubemx·keil
海滩游侠4 天前
ARM Assembly 6: Shift 和 Rotate
arm开发