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的同义词。

相关推荐
染指11101 天前
45.第二阶段x86游戏实战2-hook监控实时抓取游戏lua
汇编·c++·windows·反游戏外挂·游戏逆向
ARM&开发(Haidong)1 天前
ARM 汇编指令
汇编
烬奇小云1 天前
使用 unicorn 和 capstone 库来模拟 ARM Thumb 指令的执行,并实现多个钩子(hook)来监控代码执行、系统调用和内存读写操作(二)
java·arm开发·python
CYRUS STUDIO1 天前
Android 下内联汇编,Android Studio 汇编开发
android·汇编·arm开发·android studio·arm
艾格北峰2 天前
STM32 BootLoader 刷新项目 (九) 跳转指定地址-命令0x55
arm开发·stm32·单片机·嵌入式硬件
我不是程序猿儿3 天前
【数据结构】汇编 、机器语言 高级语言 简析。
汇编·机器语言·高级语言
橘色的喵3 天前
嵌入式ARM平台Linux网络实时性能优化
linux·网络·arm开发·性能优化·实时·内核优化
zhuqiyua3 天前
c文件的编译,汇编,基础知识
c语言·汇编·算法
荣世蓥4 天前
2.ARM_ARM是什么
arm开发
憧憬一下4 天前
Linux 内核中断描述符 (irq_desc) 的初始化与动态分配机制详解
arm开发·嵌入式硬件·嵌入式·c/c++·linux驱动开发