ARM汇编基础知识

1。RISC和CISC

RISC:精简指令集,多条简单指令完成一项任务

CISC:复杂指令集,一条指令完成一项任务

 

2.统一编址和独立编址

统一编址:IO外设和内存使用同一段内存空间,外设会消耗寻址空间资源

独立编址:IO外设和内存使用不同的内存空间,外设不占用消耗寻址空间资源

 

3.哈佛结构和冯诺依曼结构

哈佛结构:程序和数据分开独立存放,安全性高

冯诺依曼结构:程序和数据不区分放在一起

 

4.ARM汇编8种寻址方式

4.1 立即数寻址

MOV R0,#64  ;64赋值给R0寄存器
ADD R0, R0, #1  ;  R0   ← R0 + 1
SUB R0, R0, #0X3D  ;  R0   ← R0 – 0X3D

4.2 寄存器寻址

ADD R0,R1,R2 ;R0  ← R1 + R2
MOV R0, R1       ; R0 ← R1         

4.3 寄存器间接寻址

LDR R0,[R1]  ;取寄存器R1的值作为操作数的地址,把取得操作数传送到R0中

4.4 寄存器偏移寻址

MOV R0,R2,LSL  #3   ;R0 ← R2 * 8 ,R2的值左移3位,结果赋给R0。

MOV R0,R2,LSL  R1 ;R2的值左移R1位,结果放入R0。

4.5 寄存器基址变址寻址

LDR R0,[R1,#4]  ;R0 ←[R1 + 4],将R1的内容加上4形成操作数的地址,取得的操作数存入寄存器R0中。

LDR R0,[R1,#4]!;R0 ←[R1 + 4]、R1 ←R1 + 4,将R1的内容加上4形成操作数的地址,取得的操作数存入寄存器R0中,然后,R1的内容自增4个字节。其中!表示指令执行完毕把最后的数据地址写到R1。

4.6 多寄存器寻址

LDMIA  R0,{R1,R2,R3,R4}  ; LDM:Load Data from Memory to Register. R1←[R0],R2←[R0+4],R3←[R0+8],R4←[R0+12]
LDMIA  R0,{R1-R4}  ;功能同上。

4.7 相对寻址

BL   NEXT  ;相对寻址,跳转到NEXT处执行。

4.8 堆栈寻址

STMFD  SP!, {R1-R7, LR} ; STM: Store Data From register to Stack (Memory). 将R1-R7, LR压入堆栈。满递减堆栈。

LDMED  SP!, {R1-R7, LR};将堆栈中的数据取回到R1-R7, LR寄存器。空递减堆栈。

 

5.ARM常用指令

5.1 数据传输指令

MOV  R0, R1  ; R1的值传给R0
MOV  R1, #3 ; 立即数3传给

MVN  R1, R2 ; R2取反后传给R1
MVN  R2, #5 ; 5取反后传给R

5.2 加载存储指令

LDR  R0, [R1]  ; R1的值当成地址,再从这个地址装入数据到R0 (R0=*R1)
LDR  R1, =0x30008000 ; 把地址0x30008000的值装入到R1中,LDR中用常数要用=打头.(注意跟MOV的区别,MOV是#)

  STR  R0, [R1] ; 把R0的值,存入到R1对应地址空间上(*R1 = R0)

  STR  R0, =0x30008000 ; 把R0中值存入到地址0x30008000

5.3 算术运算指令

复制代码
ADD  R0, R1, R2  ; R0=R1+R2
ADD  R0, R1, #3  ; R0=R1+3

 SUB  R0, R1, R2  ; R0=R1-R2

 SUB  R0, R1, #3  ; R0=R1-3


 MUL  R0, R1, R2  ; R0=R1*R2

 MUL  R0, R1, #3  ; R0=R1*3

复制代码

5.4 位操作指令

复制代码
AND  R0, R1, R2  ; R0=R1 & R2
AND  R0, R1, #0xFF  ; R0=R1 & 0xFF

ORR  R0, R1, R2  ; R0=R1 | R2
ORR  R0, R1, #0xFF  ; R0=R1 | 0xFF

ST  R1, #0xffe  ; 等同于if(R1 & 0xffe)
TST  R1, #%1  ; 测试最低位是否为1,%表示二进制

; 清位操作 BIC R0,R0,#0xF ; 等同于 R0 &=~(0xF) BIC R0,R0,#%1011 ; 该指令清除 R0 中的位 0 1 3,其余的位保持; %表示是二进制,0x表示十六进制
复制代码

5.5 比较指令

; CMP比较两个操作数,并把结果存入CPSR供下一句语句使用

CMP  R0, R1  ; 比较R0,R1

5.6 多寄存器传输指令

复制代码
; 类似于一次传一个BUFFER到寄存器当中,或反过来.后面一般要接一个地址改变方法
; LDM 从BUFFER传数据多个寄存器传输数据到
LDMIA  R0!, {R3-R9}  ; 加R0指向的地址上连续空间的数据,保存到R3-R9当中,!表示R0值更新,IA后缀表示按WORD递增
LDMFD  SP!, {R0-R7, PC}^ ; 恢复现场,异常处理返回,^表示不允许在用户模式下使用。 ; STM 从寄存器列表向存储空间传值。 STMIA  R1!, {R3-R9} ; 将R3-R9的数据存储到R1指向的地址上,R1值更新。 STMFD  SP!, {R0-R7, LR} ; 现场保存,将R0~R7,LR入栈 STMFD sp!, {r8-r9} ; 把SP寄存器对庆的地址的值存到R8,R9当中.!表示最后的值写入SP中。Fd表示
复制代码

5.7 跳转指令

复制代码
如实现类似C语言的Return语句,就是用
MOV  PC, LR  ; 函数返回

B指令(Branch)表示无条件跳转.
B  main  ; 跳转到标号为main地代码处

BL指令(Branch with Link)表示带返回值的跳转.
BL比B多做一步,在跳转前,BL会把当前位置保存在R14(即LR寄存器),当跳转代码结束后,用MOV PC,LR指令跳回来,这实际上就是C语言执行函数的用法,
汇编里调子程序都用BL,执行完子函数后,可以用MOV PC,LR跳回来.
BL  delay  ; 执行子函数或代码段delay ,delay可以为C函数.

与 MOV  PC, XXX 能在4G空间跳转不同,B语句只能32M空间跳转,(因为偏移量是一个有符号26bit的数值=32M)
复制代码

 

posted @   灰灰5471  阅读(301)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示