跳转指令:实现程序的跳转,本质就是修改了PC寄存器
main函数中调用子函数
MAIN: @这个只是一个标号,不是指令
MOV R1, #1
MOV R2, #2
MOV R3, #3
MOV PC, #0x18 @0x18是因为指令按照顺序存储,FUNC函数的起始位置是 MOV R6, #6 从上往下数是0x18
MOV R4, #4
MOV R5, #5
FUNC:
MOV R6, #6
MOV R7, #7
MOV R8, #8
B
),本质就是将PC寄存器的值修改成跳转标号下指令的地址MAIN:
MOV R1, #1
MOV R2, #2
MOV R3, #3
B FUNC
MOV R4, #4
MOV R5, #5
FUNC:
MOV R6, #6
MOV R7, #7
MOV R8, #8
MAIN:
MOV R1, #1
MOV R2, #2
MOV R3, #3
BL FUNC
MOV R4, #4
MOV R5, #5
FUNC:
MOV R6, #6
MOV R7, #7
MOV R8, #8
MOV PC, LR @如果不自己添加返回代码是无法跳转回去,BL指令会保存地址在LR,所以我们直接调用LR的内容就行
条件码不是指令
CMP
指令的本质就是一条减法指令(SUBS),只是没有将运算结果存入目标寄存器
如何比较:根据CPSR中的(N,Z,C,V)
MOV R1, #1
MOV R2, #2
CMP R1, R2
BEQ FUNC
@ 执行逻辑:if(EQ(R1和R2相等)){B FUNC} 本质:if(Z==1){B FUNC}
BNE FUNC
@ 执行逻辑:if(NQ){B FUNC} 本质:if(Z==0){B FUNC}
MOV R3, #3
MOV R4, #4
MOV R5, #5
FUNC:
MOV R6, #6
MOV R7, #7
ARM指令集中大多数指令都可以带条件码后缀
Load/Srore指令:访问(读写)内存
Load:加载:LD开头指令一般用于读内存数据
Srore:存储:ST一般用于数据存在内存
[R2]:地址一定要写在中括号里面
@ 写内存
MOV R1, #0xFF000000
MOV R2, #0x40000000 @任何芯片都有芯片的规划
STR R1, [R2]
@ 将R1寄存器中的数据写入到R2指向的内存空间
@ 读内存
LDR R3, [R2]
@ 将R2指向的内存空间中的数据读取到R3寄存器
可以验证两个知识点
- ARM是小端对齐
- ARM是四的整数倍存储
如何在仿真环境查看地址
@ 读/写指定的数据类型
MOV R1, #0xFFFFFFFF
MOV R2, #0x40000000
STRB R1, [R2] @写入一个字节
@ 将R1寄存器中的数据的Bit[7:0]写入到R2指向的内存空间
STRH R1, [R2] @写入
@ 将R1寄存器中的数据的Bit[15:0]写入到R2指向的内存空间
STR R1, [R2] @写入
@ 将R1寄存器中的数据的Bit[31:0]写入到R2指向的内存空间
B
后缀:写入1个字节
H
后缀:写入2个字节默认:四个字节
寻址方式:就是CPU去寻找操作数的方式
从立即数中获取
@ 立即寻址
MOV R1, #1
ADD R1, R2, #1
从寄存器中获取
@ 寄存器寻址
ADD R1, R2, R3
@ 寄存器移位寻址
MOV R1, R2, LSL #1
@ 寄存器间接寻址
STR R1, [R2]
@ 基址加变址寻址
MOV R1, #0xFFFFFFFF
MOV R2, #0x40000000
MOV R3, #4
STR R1, [R2,R3]
@ 将R1寄存器中的数据写入到R2+R3指向的内存空间
STR R1, [R2,R3,LSL #1]
@ 将R1寄存器中的数据写入到R2+(R3<<1)指向的内存空间
@ 前索引
MOV R1, #0xFFFFFFFF
MOV R2, #0x40000000
STR R1, [R2,#8]
@ 将R1寄存器中的数据写入到R2+8指向的内存空间,R2没有变化
C语言中数组,数组名是地址不变,改变其中内容:
C语言:c[10]; c[2] = ‘A’
汇编:add c+2
用前索引就省去了add
@ 后索引
MOV R1, #0xFFFFFFFF
MOV R2, #0x40000000
STR R1, [R2],#8
@ 将R1寄存器中的数据写入到R2指向的内存空间,然后R2自增8
集合了上面两种
@ 自动索引
MOV R1, #0xFFFFFFFF
MOV R2, #0x40000000
STR R1, [R2,#8]!
@ 将R1寄存器中的数据写入到R2+8指向的内存空间,然后R2自增8
以上寻址方式和索引方式同样适用于LDR
1.使用汇编语言实现100以内的正整数之和
注:将最终的运算结果存储在R2寄存器
.text @ 表示当前为代码段
.global _start @ 将_start定义为全局符号
_start: @ 汇编的入口
.global _start
_start:
MOV R0, #0
MOV R1, #1
MOV R2, #0
SUM_LOOP:
ADD R2, R1 @ R1加到R2里面
ADD R1, #1 @ R1自加一
CMP R1, #100 @判断大于100后跳转结束
BGT SUM_END
B SUM_LOOP
SUM_END:
stop: @死循环,防止程序跑飞
B stop
.end @ 汇编的结束