该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃
分类: 嵌入式
2016-09-21 21:16:12
1.1编程概述
为什么学习汇编:①boot loader ②内核 ③对效率有特殊要求
而直接运行C语言需要堆栈的支持。
主要用途:①启动代码中的编写②对效率又特殊要求
1.2 ARM汇编分类
两种指令:
1. ARM 标准汇编:适用于ARM公司的汇编器,适合在Windows平台下使用,如ADS中使用。
2. GNU 汇编:适用于GNU交叉编译工具链中的汇编器,适合于Linux开发平台。
1.3 汇编程序框架
.section .data
< 初始化的数据>
.section .bss
< 未初始化的数据>
.section .text
.global _start
_start:
<汇编代码>
2.1 算数逻辑指令MOV{条件}{S} [dest],[op_1]dest = op_1@MOV instruction examplemov r1, #8mov r2, r1mov r3,#10
MVN{条件}{S} [dest],[op_1]dest = !op_1@MVN instruction examplemvn r1, #0b10mvn r2, #5mvn r3, r1
SUB{条件}{S}
[dest],[op_1],[op_2]
dest = op_1 - op_2@sub instruction example
mov r2, #4sub r1, r2, #2
mov r0, #1sub r3, r1, r0AND{条件}{S} [dest],[op_1],[op_2]
dest = op_1 AND op_2
真值表:
op_1 op_2 结果 0 0 0 0 1 0 1 0 0 1 1 1
@and instruction examplemov r1, #5and r2, r1, #0;
mov r1, #5and r2, r1, #1;
BIC{条件}{S}
[dest],[op_1],[op_2]
dest = op_1 AND (!op_2)真值表:
op_1 op_2 结果 0 0 0 0 1 0 1 0 1 1 1 0
@bic instruction examplemov r1, #0b101011bic r2, r1, #0b101
2.2 比较指令CMP{条件}{P}[op_1],[op_2]
status = op_1 - op_2改变的是CPSR中的N位和Z位@cmp instruction examplemov r1, #2cmp r1, #1bl func1 @b func1
mov r1, #2cmp r1, #3
func1:mov r1, #2mov r2, #3mov pc, lr
mov r1, #2cmp r1, #2
TST{条件}{P}[op_1],[op_2]
Status = op_1 AND op_2CPSR的Z位@tst instruction examplemov r1, #0b101tst r1, #0b001
mov r1, #0b101tst r1, #0b102.3 跳转指令
b和bl的区别在于bl会把地址保存到PC。使子函数可以用mov pc,lr返回跳转之前
@b instruction example
mov r1, #5
mov r2, #6
cmp r1, r2
bgt branch1
add r3, r1, r2
b end
branch1:
sub r3, r1, r2
end:
nop
2.4 移位指令
LSL逻辑或算术左移(Logical or Arithmetic Shift Left)ror逻辑右移(Logical Shift Right)@ror instruction examplemov r1, #0b11mov r2, r1, ror#1
@lsl instruction examplemov r1, #0b1mov r2, r1, lsl#2
2.5 程序状态字访问指令
msr:寄存器赋值到CPSR
mrs: CPSR赋值到寄存器
@program stauts
mrs r0, cpsr
orr r0, #0b100
msr cpsr, r0
2.6 存储器访问指令LDR{条件} Rd, <地址>STR{条件} Rd, <地址>LDR{条件}B Rd, <地址>STR{条件}B Rd, <地址>
@str ldr instruction example
mov r0, #0xff
mov r1, #0x30001000
str r0, [r1]
ldr r2, [r1]
3.定义类伪指令
伪/指令本身并没有所对应的机器码,它只是在编译的时候起作用,或者转化为其他的实际指令来运行。
3.1 nop
3.2 ldr
mov r0,#0xff
ldr r0,=0x1ff
此处ldr是一个伪指令,因为这个0x1ff是超过了一个字节。如果使用ldr来读取内存的话,会报错。然而加上一个‘=‘号,ldr变成了另外一条指令(伪指令)。这条指令就可以读取不受字节数影响。