目录
[3.1 数据搬移指令mov/mvn](#3.1 数据搬移指令mov/mvn)
[① 示例](#① 示例)
[② 立即数](#② 立即数)
[3.2 移位操作指令lsl/lsr/asr/ror](#3.2 移位操作指令lsl/lsr/asr/ror)
[3.3 位运算操作指令and/orr/eor/bic](#3.3 位运算操作指令and/orr/eor/bic)
[① 示例1](#① 示例1)
[② 示例2](#② 示例2)
[3.4 算数运算操作指令add/adc/sub/sbc/mul](#3.4 算数运算操作指令add/adc/sub/sbc/mul)
[① 实现两个64位数相加](#① 实现两个64位数相加)
[② 实现两个64位数相减](#② 实现两个64位数相减)
[③ 乘法指令](#③ 乘法指令)
[3.5 比较指令cmp](#3.5 比较指令cmp)
[① 条件指令](#① 条件指令)
[② 示例](#② 示例)
[① 练习](#① 练习)
[6.1 单寄存器操作指令](#6.1 单寄存器操作指令)
[① 读写代码练习](#① 读写代码练习)
[② 特殊读写格式](#② 特殊读写格式)
[③ 验证keil软件存储方式](#③ 验证keil软件存储方式)
[6.2 多寄存器操作指令](#6.2 多寄存器操作指令)
[① 练习](#① 练习)
[6.3 栈指针操作指令](#6.3 栈指针操作指令)
[① 满压栈、空增栈压入数据过程](#① 满压栈、空增栈压入数据过程)
[② 练习代码1](#② 练习代码1)
[③ 栈使用场合1](#③ 栈使用场合1)
[④ 栈使用场合2](#④ 栈使用场合2)
[7.1 汇编调用C](#7.1 汇编调用C)
[7.2 C调用汇编](#7.2 C调用汇编)
[7.3 内联汇编](#7.3 内联汇编)
一、汇编中三种符号(汇编指令、伪指令、伪操作)
二、汇编基本格式
三、数据操作指令
3.1 数据搬移指令mov/mvn
① 示例
② 立即数
vbnet
0xff000000 =====>判断的数
1111 1111 0000 0000 0000 0000 0000 0000 =====>判断的数
0000 0000 0000 0000 0000 0000 1111 1111 =====>找到0xff这个数 =====> 循环右移8位
0xf0000000 =====>判断的数
1111 0000 0000 0000 0000 0000 0000 0000 =====>判断的数
0000 0000 0000 0000 0000 0000 0000 1111 =====>找到0xf这个数 =====> 循环右移4位
0xf000000f =====>判断的数
1111 0000 0000 0000 0000 0000 0000 1111 =====>判断的数
0000 0000 0000 0000 0000 0000 1111 1111 =====>找到0xff这个数 =====> 循环右移4位
0x1FE00000=====>判断的数
0001 1111 1110 0000 0000 0000 0000 0000 =====>判断的数
0000 0000 0000 0000 0000 0000 1111 1111 =====>找到0xff这个数 =====> 循环右移11位
0x1F800000=====>判断的数
0001 1111 1000 0000 0000 0000 0000 0000 =====>判断的数
0000 0000 0000 0000 0000 0000 0111 1110 =====>找到0x7E这个数 =====> 循环右移10位
3.2 移位操作指令lsl/lsr/asr/ror
示例
vbnet
mov r0,#0xff
@ 1.将r0寄存器中的值,逻辑左移4位,赋值给目标寄存器r1,值
lsl r1,r0,#0x4 @ r1 = r0 << 4 = 0xff0
@ 0000 0000 0000 0000 0000 0000 1111 1111
@ 0000 0000 0000 0000 0000 1111 1111 0000
@ 2.将r1寄存器中的值,逻辑右移4位,赋值给目标寄存器r2,值 r2 = r1 >> 4
lsr r2,r1,#0x4 @ r2 = r1 >> 4 = 0xff
@ 0000 0000 0000 0000 0000 1111 1111 0000
@ 0000 0000 0000 0000 0000 0000 1111 1111
@ 3.将r2寄存器中的值,循环右移4位,赋值给目标寄存器r3,值
ror r3,r2,#0x4 @ r3 = 0xf000000f
@ 0000 0000 0000 0000 0000 0000 1111 1111
@ 1111 0000 0000 0000 0000 0000 0000 1111
ldr r4,=0x800000ff
@ 4.将r4寄存器中的值,算数右移4位,赋值给目标寄存器r5,值
asr r5,r4,#0x4 @ r5 = 0xf800000f
@ 1000 0000 0000 0000 0000 0000 1111 1111
@ 1111 1000 0000 0000 0000 0000 0000 1111
3.3 位运算操作指令and/orr/eor/bic
① 示例1
② 示例2
3.4 算数运算操作指令add/adc/sub/sbc/mul
① 实现两个64位数相加
vbnet
@第一个64位数:高32位用r0表示0x3 低32位用r1表示0xffffffff
@第二个64位数:高32位用r2表示0x4 低32位用r3表示0x1
@实现两个64位数相加:高32位相加r4,低32位相加r5
ldr r0,=0x3
ldr r1,=0xffffffff
ldr r2,=0x4
ldr r3,=0x1
adds r5,r1,r3 @ r5 = r1 + r3 = 0xffffffff + 0x1 = 0x0 ===> add 影响CPSR寄存器的C位
adc r4,r0,r2 @ r4 = r0 + r2 = 0x3 + 0x4 + C = 0x8 ===> adc
② 实现两个64位数相减
vbnet
@第一个64位数:高32位用r0表示0x7 低32位用r1表示0x4
@第二个64位数:高32位用r2表示0x4 低32位用r3表示0x5
@实现两个64位数相减法:高32位相加r4,低32位相加r5
ldr r0,=0x7
ldr r1,=0x4
ldr r2,=0x4
ldr r3,=0x5
subs r5,r1,r3 @ r5 = r1 - r3 = 0x4 - 0x5 = 0xffffffff ===> sub 影响CPSR寄存器的C位
sbc r4,r0,r2 @ r4 = r0 - r2 = 0x7 - 0x4 - !C = 0x2 ===> sbc
③ 乘法指令
3.5 比较指令cmp
① 条件指令
② 示例
四、跳转指令
① 练习
五、特殊功能寄存器操作指令
六、内存操作指令
6.1 单寄存器操作指令
① 读写代码练习
② 特殊读写格式
vbnet
ldr r0,=0x40000800 @ 准备一块地址空间
ldr r1,=0x11111111 @ r1 = 0x11111111
ldr r2,=0x22222222 @ r1 = 0x22222222
ldr r3,=0x33333333 @ r1 = 0x33333333
@仿真时,思考1)寄存器写到哪一块地址空间中,2)观察r0寄存器中的值变化
@将r1寄存器中的值,写到r0+4地址空间中,r0寄存器中的值没有发生变化
@ [0x40000804] = 0x11111111 r0 = 0x40000800
str r1,[r0,#4]
@将r2寄存器中的值,写到r0地址空间中,r0寄存器中的值+4
@ [0x40000800] = 0x22222222 r0 = 0x40000804
str r2,[r0],#4
@将r3寄存器中的值,写到r0+4地址空间中,r0寄存器中的值+4
@ [0x40000808] = 0x33333333 r0 = 0x40000808
str r3,[r0,#4]!
③ 验证keil软件存储方式
6.2 多寄存器操作指令
① 练习
6.3 栈指针操作指令
① 满压栈、空增栈压入数据过程
② 练习代码1
③ 栈使用场合1
vbnet
ldr sp,=0x40000800 @ 准备一块地址空间
mov r0,#0x1 @ r0 = 0x1
mov r1,#0x2 @ r1 = 0x2
bl add1_func @ 跳转到add1_func函数
add r0,r0,r1 @ r0 = r0 + r1 = 0x3
b stop
add1_func:
@ 压栈保存现场 r0 = 0x1 r1 = 0x2
stmfd sp!,{r0-r1}
mov r0,#0x3 @ r0 = 0x3
mov r1,#0x4 @ r1 = 0x4
add r0,r0,r1 @ r0 = r0 + r1 = 0x7
@ 出栈保存现场 r0 = 0x1 r1 = 0x2
ldmfd sp!,{r0-r1}
mov pc,lr @ pc = lr
④ 栈使用场合2
vbnet
_start: @指定汇编中函数入口
ldr sp,=0x40000800 @ 准备一块地址空间
mov r0,#0x1 @ r0 = 0x1
mov r1,#0x2 @ r1 = 0x2
bl add1_func @ 跳转到add1_func函数,保存函数返回地址到LR寄存器中
add r0,r0,r1 @ r0 = r0 + r1 = 0x3
b stop
add1_func:
@ 压栈保存现场 r0 = 0x1 r1 = 0x2
stmfd sp!,{r0-r1,lr}
mov r0,#0x3 @ r0 = 0x3
mov r1,#0x4 @ r1 = 0x4
bl add2_func @跳转到add2_func函数,保存函数返回地址到LR寄存器中
add r0,r0,r1 @ r0 = r0 + r1 = 0x7
@ 出栈保存现场 r0 = 0x1 r1 = 0x2
ldmfd sp!,{r0-r1,pc}
add2_func:
@ 压栈保存现场 r0 = 0x3 r1 = 0x4
stmfd sp!,{r0-r1}
mov r0,#0x5 @ r0 = 0x5
mov r1,#0x6 @ r1 = 0x6
add r0,r0,r1 @ r0 = r0 + r1 = 0xB
@ 出栈保存现场 r0 = 0x3 r1 = 0x4
ldmfd sp!,{r0-r1}
mov pc,lr
七、混合编程
7.1 汇编调用C
汇编文件编写
vbnet
ldr sp,=0x40000800 @ 初始化栈指针
mov r0,#0x1
mov r1,#0x2
mov r2,#0x3
mov r3,#0x4
bl add_func
C函数编写
cs
int add_func(int a,int b,int c,int d)
{
return (a+b+c+d);
}
7.2 C调用汇编
汇编启动文件编写:start.s文件
vbnet
ldr sp,=0x40000800 @ 初始栈指针
b main @ 跳转到C函数入口
C语言main函数入口:main.c文件
cs
int sum1 = 0;
int add1_func(int a,int b,int c,int d);
int main()
{
sum1 = add1_func(1,2,3,4);
while(1);
return 0;
}
汇编实现加法函数编写:add.s文件
vbnet
@ 实现r0-r3相加,并且通过r0返回
.text
.global add1_func
add1_func:
add r0,r0,r1
add r0,r0,r2
add r0,r0,r3
mov pc,lr
.end