上图的例子中,数值a原来是保存在内存里的,执行了某条指令后,它的值被读入内存,那问题来了:
1.什么指令,可以让CPU从内存里把数据读进来?
比如:
mov r3, #addr_a // 把变量a的地址传给CPU寄存器r3,#addr_a为立即寻址
ldr r0, [r3] // 从r3所指的内存把数值读进CPU寄存器r0,加方括号 [ ] 表示一种间接的取操作数方式,有点类似于C语言中的指针概念。
2.读进来后,这个数保存在哪里?
当然是保存在CPU内部了,存在某个寄存器里,上面的代码用寄存器r0来保存该值
3.如何处理数据?
CPU执行加法指令,比如:
add r0, r0, r1 // 在CPU内部,r0=r0+r1
4.最终数据怎么写入内存?
CPU执行指令,比如:
str r0, [r3] // 将r0的值写入r3所指的内存
上面例子中,mov、add、ldr、str等都是汇编指令,或者说它们是“助记符”──帮助我们记忆的。
记忆什么呢?这些指令其实是一个一个数值,我们去记这些数值有难度,所以就用mov、add表示不同指令对应的数值。在下面的表格中,op1对应bit[27:25],不同的op1对应不同的指令。我们就用mov、add等等来表示这些值。
注意,op1只是指令,它只占据3位(bit[27:25]),一条完整的指令还需要更多参数。比如“mov r1, r0”里面的r1、r0就是参数。这些参数也是保存在同一个32位数里。
这个32位数值就是机器码,即汇编指令是机器码的助记符。
ARM指令机器码是有一定格式,如下:
cond | op1 | op | 指令类型 |
not 1111 | 00x | - | 数据处理和杂项指令,如MOV |
not 1111 | 010 | - | 加载/存储指令,如LDR/STR |
not 1111 | 011 | 0 | 加载/存储指令,如LDR/STR |
not 1111 | 011 | 1 | 媒体指令(英文:Media instructions) |
not 1111 | 10x | - | 分支指令,如B、BL; 块数据传输指令,如LDM/STM、POP/PUSH |
not 1111 | 11x | - | 协处理器指令 |
1111 | - | - | 无条件指令,如BL |
下面讲解几种常用的汇编指令。
参考资料:
Ÿ 文件名:ARMv7编程手册(DEN0013D_cortex_a_series_PG).pdf
Ÿ 文档所在目录: 网盘开发板配套资料“08_Reference material (ARM,NXP参考资料)/Arm架构参考资料.zip”
Ÿ 参考章节: 《3: ARM Processor Modes and Registers》