ARM汇编指令集

本文介绍了ARM汇编指令集中的LDR/STR、寻址方式、指令后缀、条件后缀、多级指令流水线等内容,并通过实例解析了各种指令的使用,包括数据移动、逻辑运算、比较和跳转等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

汇编特点

LDR/STR架构:CPU不能直接处理内存,只能读寄存器,因此需要将内存的内容拷贝到寄存器后再处理。

LDR(load register):内存->寄存器;

STR(store register):寄存器->内存;

8种寻址方式

  • 寄存器寻址:       mov r1, r2      //把r2的内容移动到r1;
  • 立即寻址:         mov r0, #0xff00 //把数字0xff00移动到r0;
  • 寄存器移位寻址:    mov r0,r1,lsl#3 //把r1的内容左移3位(乘8)后再放入r1;
  • 寄存器间接寻址:    mov r0,[r2]    //以r2内的数据为目标地址把数据移动到r0;
  • 变址寻址:         mov r1,[r2,#4]//以r2内的地址加4作为最终目标地址访问内存,把内存的数据移动到r0;
  • 多寄存器寻址:     ldmia r1!,{r2-r7,r12}  以r1内存的地址为首地址,连续向后访问8个地址,分别移动到R2-R7和r12中;
  • 堆栈寻址:         stmfd sp!,{r2-r7,lr}   以SP指向的内存的地址为首地址,连续向后访问8个地址,分别移动到R2-R7和lr中;
  • 相对寻址:         beq flag               跳转到标号flag位置去运行;

指令后缀

  • B(byte)         功能不变,操作长度变为8位;如ldrb
  • H(half word)    功能不变,操作长度变为16位;如ldrh
  • S(signed)       功能不变,操作数为有符号位;如ldrsb,ldrsh;
  • S(S标志)       功能不变,影响CPSR,运算结果为0将CPSR中的z位变成1;

条件后缀

条件满足才执行;

  • moveq r0,r1         如果eq(上一行语句的结果(CPSR的z位为1))成立则执行本条语句,类似if(z==1){r0=r1};仅影响自己,不影响前后语句。
  • movne r0,r1         如果ne(上一行语句的结果(CPSR的z位为0))成立则执行本条语句,类似if(z==0){r0=r1};仅影响自己,不影响前后语句。

多级指令流水线

取数据->解码->执行;同时执行,在执行的时候解码,解码下一句,读取下下一句;

pc指向的是取数据的地址,因此有时候在中断返回的时候需要将PC的值减去8;

spv2150一共有13级流水

指令

  • mov r1, r2      只能操作寄存器,把r2的内容移动到r1;
  • mvn r1, r2      只能操作寄存器,把r2的内容按位取反后移动到r1;
  • add             加
  • sub             减
  • and             逻辑与
  • orr             逻辑或
  • eor             逻辑异或
  • bic r0,r1,#0x1f 位清除;将r1中的0x1f为1的位清零后给r0;
  • spsr和cpsr访问指令:每个模式都有1个独立的spsr,整个芯片只能有1个cpsr,spsr就是用来保存当前模式的cpsr,便于跳转后回来时恢复。
  • mrs r0, cpsr    读CPSR;CPSR->R0
  • msr cpsr, r0    写CPSR;R0->CPSR

比较指令:

没有结果,只改变cpsr的z位。

  • cmp r0,r1  比较r0、r1是否相等,相减后结果为0,
  • cmn r0,r1  比较r0、r1是否互为补数,相加后结果是否为0,
  • test r0 #0x01 测试r0的第0位是否为1.
  • teq r0,r1  比较r0、r1是否相等,两个数异或,

跳转

  • b直接跳转,且不回来
  • bl跳转前先将地址存lr地址,回来后接着执行,例如函数调用;
  • ldr(load register):内存->寄存器;

ldr r0, = 0x11111111  //有=号表示该指令伪指令

  • str(store register):寄存器->内存;

str r0,[r1]           //把R0的值写入到R1存储的地址的内存。

批量访问

  • ldm 多个内存->寄存器;
  • stm 多个寄存器->内存;

访存指令

swp r1,r2,[r0];将r0指向的内存的数据给r1,将r2的数据移动到r0中内存的地址中。

swp r1,r1,[r0];交换r1与r0指向的内存,将r0的存的地址的内容放到r1,将r1的数据移动到r0中内存的地址中。

协处理器CP15操作指令:

mrc 读取cp15;

mrc p15,0,r0,c1,c0,0;将cp15的c1寄存器读取到r0;

mcr 写cp15;

mcr p15,0,r0,c1,c0,0;将寄存器r0的内容写入cp15的c1;

多寄存器访问:

stmia sp,{r0-r12};将r0-r12读取放在以sp为首地址的后面13个寄存器,每次存一次后地址再加4;

stmib sp,{r0-r12};将r0-r12读取放在以sp为首地址的后面13个寄存器,每次地址加4后再存;

后缀

后缀ia:先传输,再地址加4

后缀fb:先地址加4,再传输;(常用,行业默认使用)

后缀da:先传输,再地址减4

后缀db:先地址减4,再传输;

伪指令:

与编译器有关,不同编译器,伪指令不同

@  汇编注释,也可使用//

: 标号

.  当前指令地址,类似while,b . 

#  立即数

.ldr  大范围的地址加载(长范围),该伪指令不用判断数据的合法性;如ldr r0,=0xfff;将立即数放入R0,

.adr  小范围的地址加载(附近),该伪指令不用判断数据的合法性;如ldr r0,=0xfff;将立即数放入R0,

.section

伪指令,用于给代码去段名

__HEAD      .section    ".head.text","ax"//给接下来的代码取一个段名.head.text,用户自定义段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值