汇编语言的组成
伪操作
不参与程序的执行,但是用于告诉编译器程序该怎么编译 如:
.text .global .end .if .else .endif .data
汇编指令
汇编器将一条汇编指令编译成一条机器码,在内存里一条指令占4字节内存,一条指令可以实现一个特定的功能。
伪指令
不是指令,但是看似一条指令,可以实现指令类似的功能,一条伪指令可能是由多条指令共同实现。
注释
单行注释:@
多行注释:/**/
条件编译
.if 0
@text
.else
@text
.endif
汇编指令的介绍
基本数据操作指令
数据搬移指令:=
数据位移指令:<< >>
数据算数运算指令:+ - * /
位运算指令:$ | ~ ^
数据比较指令:cmp 第一操作数,第二操作寄存器,其有很多条件码,如果条件码满足则执行对应的指令
跳转指令
内存读写指令
状态寄存器读写指令
软中断指令
汇编指令的基本语法格式
基本格式: <opcode>{cond}{s} Rd,Rn,#oprand2
解释:
opcode:指令码
cond:条件码
指令不加条件码,指令默认无条件执行
指令加条件码,指令有条件执行
s:状态位
指令不加s,指令执行的结果不会影响CPSR寄存器
指令加s,指令执行的结果会影响CPSR寄存器
Rd:目标寄存器
Rn:第一操作寄存器
#oprand2:第二操作数
1)立即数
2)有效数:将一个数取反之后,变成立即数
3)寄存器
4)经过移位的寄存器
注意事项:
1)汇编指令中不区分大小写
2)汇编指令不需要以;号结尾
3)<opcode>{cond}{s}:需要连在一起写
4)Rd,Rn,#oprand2:需要用逗号分隔开
5) <opcode>{cond}{s}和Rd,Rn,#oprand2需要用空格分隔开
数据搬移指令
指令码:mov mvn
格式:<opcode>{cond}{s} Rd,#oprand2
@ 代码1:
mov r0,#0xf @ r0 = 0xf
mov r1,#0xff
@ mov r2,#0xfff @ error
@ mov r3,#0xffff @ error
@ mov r4,#0xfffff @ error
mov r5,#0xffffff
mov r6,#0xfffffff
mov r7,#0xffffffff
/*------------------ ------------------ ---------------*/
@ 代码2:
mvn r5,#0xff @ 0xff按位取反之后,赋值给r5
mov r0,#0xff000000 @ 0xff 8
mov r1,#0x1f800000 @ 0x7e 10
mov r2,#0x00ffffff @ ~r2 = 0xff000000
mov r3,#0x0fffffff @ ~r3 = 0xf0000000
mov r4,#0xffffffff @ ~r4 = 0x00000000
立即数判断
要从这个数中间找到0~0xff之间的数,而且要包含所有1,如果能找到,循环右移偶数位,如果能够得到要判断的数,则该数为立即数。
伪指令
如何用伪指令将非立即数保存到寄存器中
伪指令:
LDR 目标寄存器,=数值
移位指令
格式:<opcode>{cond}{s} Rd,Rn,#oprand2
指令码:
lsl:逻辑左移 高位移出,低位补0
lsr:逻辑右移 低位移出,高位补0
asr:算数右移 有符号数右移,低位移出,高位补符号位
ror:循环右移 低位移出,补高位
位运算指令
格式:<opcode>{cond}{s} Rd,Rn,#oprand2
方法:看到清零用 & 看到置1用 |
and:按位与(&)------>与0清0,与1不变
orr:按位或(|) ------>或0不变,或1置1
eor:按位异或(^) ------>异或0不变,异或1取反
bic:按位清除 ------> 哪一位写1,对应的位进行清0
算数运算指令
指令码:add adc sub sbc mul
基本格式: <opcode>{cond}{s} Rd,Rn,#oprand2
add: 普通加法指令
adc:带进位加法指令
sub:普通减法指令
sbc:带借位减法指令
mul:乘法指令 格式:<opcode>{cond}{s} Rd,Rn
64位数据进行算数运算
原则:
一个 64位数保存在两个寄存 高32位运算,低32位运算
mov r1,#0XFFFFFFFE @保存第一个数据的低32位
mov r2,#2 @保存第一个数据的高32位
mov r3,#3 @保存第二个数据的低32位
mov r4,#4 @保存第2数据的高32位
@低32位运算要求影响条件位
ADDS R5,R1,R3 @R5保存运算后结果的低32位
ADC R6,R2,R4 @R6寄存器保存运算结果的高32位,需要考虑条件位
比较指令
指令码:cmp
基本格式: <opcode>{cond} Rn,#oprand2
1)比较指令没有目标寄存器
2)比较指令本质做减法运算
3)比较指令的执行结果会影响CPSR寄存器的NZCV位,不需要加s
4)比较指令需要和条件码搭配使用
5)前面所有学习的指令都属于无条件指令,比较指令属于有条件执行
示例:
比较两个数大小
第一个数比第二个数大:第一个数减第二个数
第一个数比第二个数小:第二个数减第一个数
mov r0,#0x3
mov r1,#0x4
cmp r0,r1
subhi r0,r0,r1 @ r0 = r0 - r1
subcc r1,r1,r0 @ r1 = r1 - r0
跳转指令
指令码:b
格式:b {cond} 标签
b指令码:有去无回,不会保存函数的返回地址到LR寄存器中
-------------------
b loop
-------------------
loop:
-------------------
/****************************************************/
指令码: bl
格式:bl{cond} 标签
bl指令码:有去有回,会保存函数的返回地址到LR寄存器中
-------------------
bl loop
------------------- ----->会保存函数的返回地址到LR寄存器中
loop:
-------------------