1、什么是汇编指令
汇编指令:是机器指令的助记符,经过编译后会得到一串01010组成的机器码,可以由cpu读取执行
伪指令:本质上不是指令,只是和指令一起写在代码中,是指导编译过程的,是编译系统提供的,不会生成对应的机器码
2、数据搬移指令(指令格式)
mov r0, #1 @将立即数1赋值给r0
mov r1,r0 @将r0的值赋值给r1
mov r2, r0, lsl #1 @将r0的值左移1位赋值给r2
mov r3, r2, lsr #2 @将r2的值右移两位赋值给r3
mvn r5,r3 @将r3取反之后赋值给r5
汇编指令的格式:
{} {s} , ,{}
其中:<>是必须的
{}是可选的
opcode:汇编指令
cond:执行条件
s:是否影响cpsr寄存器的值(cpsr的条件位)
rd:目标寄存器
rn:第一操作数寄存器,只能是寄存器
operand2:第二操作数
以mov指令为例,学习一下机器指令格式:
mov {cond} {s} rd, op2
31-28 27 26 25 24-21 20 19-16 15-12 11-0
[31-28]:条件码
27-26:预留 默认为0
25: 1 第二操作数是立即数 0 第二操作数是寄存器
24-21:操作码 mov:1101
20:1 影响cpsr的值 0 不影响cpsr的值
19-16:第一操作数寄存器
15-12:目标寄存器
11-0:第二操作数寄存器
如果是立即数:0-7位 立即数
11-8:移位值
最终的立即数 = 立即数 循环右移 (移位值*2)位
合法立即数:如果一个32位的数,可以通过0-7位的数循环右移偶数位得到就是合法的
0x00ab0000 0x0000ffff 0x10000001
E3A00001
1110 001 1101 0 0000 0000 0000 0000 0001
总结:如果立即数是0-255,绝对是合法的,可以直接使用mov指令,而如果大于255,就直接使用ldr伪指令就好
三级流水线:取指 译码 执行
pc:正在取指的指令的地址
正在执行的指令的地址 = pc-8
3、算术指令
add r0,r1,r2 @r0 = r1+r2
add r0,r1 @r0+=r1
sub @减法
mul @乘法
4、逻辑指令
and r0, r1, r2 @r0 = r1 & r2
orr r0,r1,r2 @r0 = r1 | r2
bic r0, 0xff @将r0的0-7位清0
5、比较指令
cmp r0,r1 @比较r0和r1的大小
cmp r0,#1 @比较r0和1的大小
moveq r2,#2 @当r0==1的时候,将2赋值给r2
tst r0,#0x2 @测试r0的第2位(从1算的)是否为0
moveq r2,#0xdd
movne r2,#0xee
注意:cmp和tst会自动引起cpsr值的变化
6、跳转指令
b loop @跳转到loop这个语句标号处
loop:
nop
nop
其中:nop是空指令,只占用时间,不做任何事情
loop:语句标号,表示的是它下一条指令的地址
练习:实现1-5的累加和
bl:在跳转时,会将返回地址自动保存到lr中
总结:b 循环 bl 调用函数
汇编中如何传参?
规定:r0-r3就是参数 r0是返回值
如果超过四个参数,就入栈
注意:lr = pc-4
7、内存访问指令
ldr:将内存的值拷贝到寄存器
str:将寄存器的值拷贝到内存
前提:内存是通过地址访问的
ldr r0,[r1] @将r1这个地址的内容拷贝给r0,r1存的是一块内存的首地址
@r0 = *r1
str r0,[r1] @*r1 = r0
ldr和str:四个字节
ldrb和strb: 一个字节
ldrh和strh:两个字节
拷贝字符串:
一次拷贝一个字符
ldr r0,[r1, #4] @r0 = *(r1+4)
ldr r0,[r1],#4 @r0=*r1, r1+=4
作业:
1、练习代码
2、用汇编实现以下功能
void main()
{
func1(2);
while(1);
}
int func1(int a)
{
if(2 == a)
{
return func2(a);
}
else
{
return func3(a);
}
}
int func2(int a)
{
return a+3;
}
int func3(int a)
{
return a-1;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)