当前位置: 首页 > article >正文

常见汇编指令

一、判断是否为立即数
  1. 如果某个数的数值范围是0~255之间,那么这个数一定是立即数;

  2. 把某个数展开成2进制,这个数的最高位1至最低位1之间的二进制数序列的位数不能超过8位;

  3. 这个数的二进制序列的右边必须为偶数个连续的 0

二、指令
2.1、mov

mov指令:加载12位立即数到寄存器或转移一个寄存器的值到另外一个寄存器

mov ro,#(立即数)

mov r0,r1(寄存器)

mov r0,r1,lsl # 2

2.2、mvn

MVN指令不同的是在传送之前,将被传送的对象先按位取反,再传送到目的寄存器。

mvn r0,r1

2.3、ldr
  • ldr寄存器加载指令:

LDR{<c>}{<q>} <Rt>, <label> ;如ldr r0, =0x2FAB4

ldr指令多用于从ram中将一个32位的字数据传送到目的寄存器中

LDR<c> <Rt>, [<Rn>{, #+/-<imm12>}] 如:

LDR   R0,[R1,#8]             ;将内存地址为R1+8的字数据读入寄存器R0,这里的#8作为12位立即数是可以省略的

LDR<c> <Rt>, [<Rn>], #+/-<imm12> 如:

ldr r0, [r1], #8 ;将内存地址R1的字数据读入r0,之后r1+8

LDR<c> <Rt>, [<Rn>, #+/-<imm12>]! 如:

LDR   R0,[R1,#8] !          ;将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R1+8写入R1。

  • 可以加载数据
  • 可以加载地址
2.4、str

`STR`指令在ARM汇编语言中用于将数据从寄存器存储到内存中。它是“Store Register”的缩写。与`LDR`指令类似,`STR`指令也有多种变体,可以执行不同类型的存储操作。下面是一些常见的`STR`指令用法:

1. **普通存储**:将寄存器中的数据存储到内存中的指定位置。
   ```assembly
   STR R0, [R1] ; 将R0寄存器中的数据存储到R1寄存器指向的内存地址中
   ```

2. **带偏移的存储**:将寄存器中的数据存储到基址寄存器加上偏移量后的内存地址中。
   ```assembly
   STR R0, [R1, #4] ; 将R0寄存器中的数据存储到R1寄存器指向的内存地址加上4的位置
   ```

3. **带负偏移的存储**:将寄存器中的数据存储到基址寄存器减去偏移量后的内存地址中。
   ```assembly
   STR R0, [R1, #-4] ; 将R0寄存器中的数据存储到R1寄存器指向的内存地址减去4的位置
   ```

4. **带索引的存储**:使用另一个寄存器的值作为偏移量进行存储。
   ```assembly
   STR R0, [R1, R2] ; 将R0寄存器中的数据存储到R1寄存器指向的内存地址加上R2寄存器的值的位置
   ```

5. **带写回的存储**:存储后更新基址寄存器的值。
   ```assembly
   STR R0, [R1], #4 ; 将R0寄存器中的数据存储到R1寄存器指向的内存地址中,并将R1的值增加4
   ```

6. **条件存储**:只有在满足特定条件时才执行存储操作。
   ```assembly
   STRNE R0, [R1] ; 如果零标志(Z)为假,则将R0寄存器中的数据存储到R1寄存器指向的内存地址中
   ```

7. **存储半字**:将寄存器中的半字(16位)数据存储到内存中。
   ```assembly
   STRH R0, [R1] ; 将R0寄存器中的低16位数据存储到R1寄存器指向的内存地址中
   ```

8. **存储字节**:将寄存器中的字节(8位)数据存储到内存中。
   ```assembly
   STRB R0, [R1] ; 将R0寄存器中的低8位数据存储到R1寄存器指向的内存地址中

2.5、bic指定位清零指令:

BIC{S}<c> <Rd>, <Rn>, #<const>;将rn中的字数据const为1的比特清零,把结果放入rd

2.6、orr指定位置位指令:

ORR{S}<c> <Rd>, <Rn>, #<const>

  • 汇编指令的s后缀,几乎所有的汇编指令都可以在指令后面加上s后缀,s后缀的含义是在指令执行过程中会更新cpsr寄存器的N,V,C,Z位

  • N:在结果是有符号的二进制补码情况下,如果结果为负数,则N=1;如果结果为非负数,则N=0
  • Z:如果结果为0,则Z=1;如果结果为非零,否则Z=0
  • C:是针对无符号数最高有效位向更高位进位时C=1;减法中运算结果的最高有效位从更高位借位时C=0
  • V:该位是针对有符号数的操作,会在下面两种情形变为1,两个最高有效位均为0的数相加,得到的结果最高有效位为1;两个最高有效位均为1的数相加,得到的结果最高有效位为0;除了这两种情况以外V位为0
2.7、cmp
  • CMP比较指令用于比较两个寄存器的值或者比较一个寄存器和立即数的值,其原理是对待比较的两个数求差,看结果是否为0,这个指令会无条件修改N,V,C,Z位。

2.8、跳转指令b

b指令类似c语言的goto语句,能够实现无条件跳转。跳转时需要一个lable,表示要跳转到什么地方去

补充:

b指令本质上就是把待跳转那行的地址装入pc寄存器,但是函数在调用完毕之后要回到调用处的下一行指令处执行,为了能够回到调用的下一行,需要使用bl指令。bl和b之间的区别就在于bl会在lr寄存器中保存回来的地址。如:

2.9、入栈保护指令stmfd(STMDB)

STMFD<c> <Rn>{!}, <registers>

其中Rn表示栈底指针寄存器,< registers >表示需要入栈保护的寄存器,!表示入栈之后sp自动自减。如:

stmfd sp!, {r0, r1, r2, r3-r12, lr}

2.10、出栈恢复指令ldmfd(LDM/LDMIA/)

LDMFD<c> <Rn>{!}, <registers>

中Rn表示栈底指针寄存器,< registers >表示需要入栈保护的寄存器,!表示出栈之后sp自动自增。如:

ldmfd sp!, {r0, r1, r2, r3-r12, lr}

三、汇编进行完成初始化

1、异常向量表初始化

	b start
	ldr pc, =do_undifined
	ldr pc, =do_swi
	ldr pc, =do_p_abort
	ldr pc, =do_d_abort
    nop
	ldr pc, do_irq
	ldr pc, do_fiq
	

do_fiq
	b do_fiq	

do_irq
	import irq_handler
	sub lr, lr, #4
	stmfd sp!, {r0-r12, lr}
	bl  irq_handler
	ldmfd sp!, {r0-r12, pc}^

do_d_abort
	b do_d_abort

do_p_abort
	b do_p_abort

do_swi
	import swi_handler
	stmfd sp!, {r0-r12, lr}
	bl  swi_handler
	ldmfd sp!, {r0-r12, pc}^

do_undifined
	b  do_undifined

2、栈顶指针初始化

//这三部分代码是将iram里面三个栈区进行初始化,对应三种不同模式下的,对应栈顶指针的值,以及模式怎么进行切换
ldr sp, =0x40001000 ;svc_sp

	mrs r0, cpsr
	bic r0, r0, #0x1F
	orr	r0, r0, #0x12
	bic r0, #(1 << 7)
	msr cpsr_c, r0

	ldr r0, =0x40001000
	sub r0, r0, #1024
	mov sp, r0

	mrs r0, cpsr
	bic r0, r0, #0x1F
	orr r0, r0, #0x10
	msr cpsr_c, r0

	ldr r0, =0x40001000
	sub r0, r0, #2048
	mov sp, r0
	
	import main


http://www.kler.cn/news/310994.html

相关文章:

  • C++系列-谓词predicate
  • AWTK fscript 中的 CRC函数
  • 转行大模型开发:挑战与机遇,如何有效学习以实现职业转变
  • 第二证券:移动物联网迎政策助力 稀土价格有望持续回暖
  • 【C++】 —— string的使用
  • [go] 适配器模式
  • 爬虫之隧道代理:如何在爬虫中使用代理IP?
  • [Leetcode] 227.基本计算器
  • Kleopatra与MinGW64中gpg冲突
  • [Linux] 通透讲解 什么是进程
  • 嵌入式常用算法之低通滤波算法
  • libgit2编译
  • 智慧课堂学生行为数据集
  • 2024最新版 Tuxera NTFS for Mac 2023绿色版图文安装教程
  • 达梦数据库导入xml迁移到达梦数据库大文件导致中断问题解决方案记录?
  • ESP8266+httpServer+GET+POST实现网页验证密码
  • 承兑汇票识别API 银行承兑汇票识别接口 电子承兑汇票识别sdk 多进程识别
  • 鸿蒙Harmony应用开发,数据驾驶舱登录页面的实现
  • 使用python-pptx插入图片:将图片添加到幻灯片中并进行位置调整
  • 实战17-NavBar+Vip布局
  • 2024年9月python二级易错题和难题大全(附详细解析)(四)
  • Spring中存储Bean的常见注解
  • python的数据类型详解
  • MyBatis系统学习(三)——动态SQL
  • 简单题28-找出字符传中第一个匹配项的下标(Java and Python)20240918
  • ElasticSearch介绍+使用
  • 3. Python计算水仙花数
  • 利士策分享,赚钱与体重:一场关于生活平衡的微妙探索
  • 云计算服务的底层,虚拟化技术的实现原理
  • 假期学习--iOS 编译链接