完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1、数据操作指令
数据搬移指令 mov:移动指令 mvn:取反移动指令 语法格式:{cond}{s} {Rd}, {oprand2} mov r0, #0xFF // 立即数0xFF放入寄存器r0 立即数前需要加“#” mov r1, r0 // 将寄存器r0的数据放入寄存器r1中 mvn r2, #0xFF // r2 = ~0xFF(0xFFFFFF00) mov r3, #0xFFFFFF // 0xFFFFFF是有效数,写入机器码会转换成立即数#~0xFF000000 mov r0, #0xFF000000 ldr r0, =0x12345678 //ldr伪指令 将0x12345678 放入寄存器r0 算数运算指令 {cond}{s} {Rd}, {Rn}, {oprand2} add :普通的加法指令 adc :带进位的加法指令 sub :普通的减法指令 ***c :带借位的减法指令 练习题1 两个64位的数相加 第一个64位的数高32位在R1,低32位在R0 第二个64位的数高32位在R3,低32位在R2 结果高32位在R5,低32位在R4 mov r0, #0xFFFFFFFE mov r1, #0x3 mov r2, #0x4 mov r3, #0x5 adds r4, r0, r2 @ r4 = r0 + r2 // s:产生进位C位置1,否则为0 adc r5, r1, r3 @ r5 = r1 + r3 + C // adc指令自动判断C位的值 将R0寄存器中的第[4]位清0的三种方法,保证其他位不变 and r0, r0, #0xFFFFFFEF and r0, r0, #(~0X10) and r0, r0, #(~(0x1 << 4)) /*and r0, #0x10000 如果目标寄存器和第一个操作寄存器编号相同,可以合并写一个。*/ 练习题2 两个64位的数减法 第一个64位的数高32位在R1,低32位在R0 第二个64位的数高32位在R3,低32位在R2 结果高32位在R5,低32位在R4 mov r0, #0xFFFFFFFE mov r1, #0x3 mov r2, #0x4 mov r3, #0x5 subs r4, r2, r0 @r4 = r2 - r0 ***c r5, r3, r1 @r5 = r3 - r1 - N 乘法指令测试 mov r0, #3 mov R1, #4 mul r2, r0, r1 //r2 = r0 * r1 // 第二个操作数只能是寄存器,不能是立即数 // mul r2, r0, #4 @ error mul r0, r1 //r0 = r0 * r1 逻辑运算指令 and:与 orr :或 eor :异或 练习: 使用位运算符 : & | ^ ~ << >> 1、将R0寄存器中的第[4]位清0,保证其他位不变 and r0, r0, #0xFFFFFFEF and r0, r0, #(~0X10) and r0, r0, #(~(0x1 << 4)) /*and r0, #0x10000 如果目标寄存器和第一个操作寄存器编号相同,可以合并写一个。*/ 2、将R0寄存器中的第[20]位置1,保证其他位不变 orr r0, r0, #(~(0x1 << 20)) 3、将R0寄存器中的第[11:8]位置1,保证其他位不变 orr r0, r0, #(0xF << 8) 4、将R0寄存器中的第[3:0]位清0,保证其他位不变 and r0, r0, #0xFFFFFFF0 5、将R0寄存器中的第[29:26]位写成1010,保证其他位不变 and r0, r0, #(~(0xF << 26)) @先清零 orr r0, r0, #(0xA << 26) @再置1 6、将R0寄存器中的第[30:25]位写成101010,保证其他位不变 and r0, r0, #(~(0x3F << 25)) @先清零 orr r0, r0, #(0x2A << 25) @再置1 2、跳转指令 b bl b :跳转、不保存返回地址到lr寄存器中 bl:跳转、自动保存返回地址到lr中 语法格式: b/bl{cond} Label Label: 汇编代码 跳转指令的本质:修改PC值 // b 不保存返回地址到lr寄存器中 .if 0 mov r0, #3 mov r1, #4 b func_add //跳转到func_add 不保存rl 没办法返回 add r2, r0, r1 b stop func_add: mov r4, #5 mov r5, #6 add r6, r4, r5 //bl 自动保存返回地址到lr中 mov r0, #3 mov r1, #4 bl func_add add r2, r0, r1 b stop func_add: mov r4, #5 mov r5, #6 add r6, r4, r5 mov pc, lr 3、load/store指令(单/多寄存器操作) 1、单寄存器操作指令 将Rn指向的内存空间中的数据读到Rm寄存器中,读4字节 Rn寄存器中的值,看成内存的地址。 ldr{code} Rm, [Rn] 将Rm寄存器中的数据写到Rn指向的内存空间中,写4字节 Rn寄存器中的值,看成内存的地址。 str{code} Rm, [Rn] ldr r0, =0x40000800 ldr r1, =0x12345678 str r1, [r0] //在0x40000000地址写入数据0x12345678 ldr r2, [r0] //将0x40000000地址的数据0x12345678写入寄存器r2 ldr r0, =0x40000800 ldr r1, =0x11111111 ldr r2, =0x22222222 ldr r3, =0x33333333 //将R1中的值存到R0+4指向的地址空间中,R0中的值不变 str r1, [r0, #4] //前索引 //将R2中的值存到R0指向的地址空间中,R0=R0+4 str r2, [r0], #4 //后索引 //将R3中的值存到R0+4指向的地址空间中,R0=R0+4 str r3, [r0, #4]! //自索引 @ 注:立即数要求是4的整数倍 @ 以上索引方式同样适用于ldr指令 @ ldrb/strb/ldrh/strh b : byte h : half @ 语法格式跟ldr和str完全一致。 多寄存器操作指令 从Rm指向的地址空间中读连续的数据到寄存器列表中, ldm Rm, {寄存器列表} 将寄存器列表中的数据写到Rm指向的连续的内存空间中。 stm Rm, {寄存器列表} 要求: @ 寄存器列表 1》 寄存器的编号要求从小到大 2》 寄存器连续使用“-”隔开 3》 寄存器不连续使用“,”隔开 ldr r0, =0x40000800 ldr r1, =0x11111111 ldr r2, =0x22222222 ldr r3, =0x33333333 ldr r4, =0x44444444 ldr r5, =0x55555555 //stm r0, {r1-r5} stm r0, {r5,r4,r3,r2,r1} //stm r0, {r1-r3,r4,r5} //ldm r0, {r6-r10} ldm r0, {r10,r9,r8,r7,r6} @ 总结:寄存器列表中的寄存器顺序不管怎样, @ 永远都是低地址对应小编号寄存器 @ 高地址对应大编号的寄存器 4、特殊功能寄存器传送指令 msr mrs 将普通寄存器(立即数)中的数据写到cpsr中 msr{cond} cpsr, rn msr{cond} cpsr, #shift 将cpsr寄存器中的值读到普通寄存器中 mrs rn, cpsr 例子:从SVC模式切换到user模式 第一种方式 msr cpsr,#0xD0 mov r0, #0xD0 msr cpsr, r0 第二种方式 mrs r0, cpsr bic r0, r0, #0x1F //and r0, r0, #(~0x1F) orr r0, r0, #0x10 msr cpsr, r0 5、软中断指令 swi /******************************/ //构建异常向量表 b reset b undef_handler b swi_handler b pref_handler b data_handler b . b irq_handler b fiq_handler reset: //初始化svc模式下的栈 ldr sp, =0x40000800 //此处的sp是svc模式下的栈指针 //从SVC模式切换到用户模式 mrs r0, cpsr bic r0, r0, #0x1F orr r0, r0, #0x10 msr cpsr, r0 //初始化用户模式下的栈 ldr sp, =0x40000900 //此处的user是svc模式下的栈指针 //开始执行代码 mov r0, #3 mov r1, #4 swi 2 //软中断指令 swi 3 //软中断指令 add r2, r0, r1 //r2 = r0 + r1 = 0x7 b stop //死循环 stop: bstop //软中断的异常处理程序 swi_handler: //保存现场 stmfd sp!, {r0-r1,lr} //获取软中断号 sub r3, lr, #4 ldr r4, [r3] bic r4, r4, #0xFF000000 //对软中断号进行判断,执行分支程序 cmp r4, #2 moveq r0, #5 cmp r4, #3 moveq r1, #6 //恢复现场 //^:恢复spsr_ ldmfd sp!, {r0-r1,pc}^ |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1817 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1631 浏览 1 评论
1103 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
739 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1692 浏览 2 评论
1951浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
755浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
586浏览 3评论
605浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
568浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-30 12:53 , Processed in 0.957909 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号