完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
在嵌入式的学习中,编程时,总会遇到一些汇编代码。。。
不过一想也是,嵌入式本身就偏底层,和硬件接触,汇编代码效率更高,总会接触的。 ----------------------------- 汇编语言是什么? 汇编语言是程序设计语言的基础语言,是唯一可以直接与计算机硬件打交道的语言。 汇编语言根据CPU的不同,也分为:ARM汇编语言、x86汇编语言 ARM汇编指令: EQU 给数字常量名取一个符号名,相当于C语言中的define AREA 汇编一个新的代码段或者数据段 SPACE 分配内存空间 PRESERVE8 当前文件栈需按照 8 字节对齐 EXPORT 声明一个标号具有全局属性,可被外部的文件使用 DCD 以字为单位分配内存,要求 4 字节对齐,并要求初始化这些内存 PROC 定义子程序,与 ENDP 成对使用,表示子程序结束 IMPORT 声明标号来自外部文件,跟 C 语言中的 EXTERN 关键字类似 B 跳转到一个标号 END 到达文件末尾 ,文件结束 IF,ELSE, ENDIF 汇编条件分支语句,跟 C 语言的 if else 类似 MRS 加在特殊功能寄存器的值到通用寄存器 MSR 存储通用寄存器的值到特殊功能寄存器 CBZ 比较,比较结果为0就转移 CBNZ 比较,比较结果非0就转移 LDR 从存储器中加载字到寄存器中l 是 LDR[伪指令] 加载一个立即数或者一个地址值到一个寄存器。例如:ldr rd, = lable 如果 label 是立即数,那 Rd 等于立即数,如果 labe一个标识符,比如指针,那存到 Rd 的就是 label 这个标识符的地址 LDRH 从存储器中加半字到一个寄存器中 LDRB 从存储器中加载字节到寄存器中 STR 把一个寄存器按字存储到存储器中 STRH 把一个寄存器存的低【半】字存储到存储器中 STRB 把一个寄存器的低字节存储到存储器中 LDMIA 将多个字从存储器加载到 CPU 寄存器,先操作,指针在递增。 STMDB 将多个字从 CPU 寄存器存储到存储器,指针先递减,再操作 ORR 按位或 BX 直接跳转到由寄存器给定的地址 BL 跳转到 标号对应的地址,并且把跳转前的下条指令地址保存到 LR BLX 跳转到由寄存器 REG 给出的的地址,并根据 REG 的 LSB 切换处理器状 态 , 还 要 把 转 移 前 的 下 条 指 令 地 址 保 存 到 LR 。 ARM(LSB=0) , Thumb(LSB=1)。CM3 只在 Thumb 中运行,就必须保证 reg 的 LSB=1 否则一个fault 打过来编译器指令: WEAK 弱定义,如果外部文件声明了一个标号,则优先使用外部文件定义的标号,如果外部文件没有定义也不出错。 ALIGN 编译器对指令或者数据的存放地址进行对齐,一般需要跟一个立即数,缺省表示 4 字节对齐------再看汇编代码并注释 __asm void xPortPendSVHandler( void ) //这个函数完成:上下文切换:上文保存、切换下文 { extern pxCurrentTCB; (1)// extern vTaskSwitchContext; (2)// PRESERVE8 (3)//当前文件栈需按照 8 字节对齐 mrs r0, psp (4)//加在特殊功能寄存器psp的值到通用寄存器r0 i*** //指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令 ldr r3, =pxCurrentTCB (5)//加载 pxCurrentTCB 的地址到 r3 ldr r2, [r3] (6)//加载r3指向的内容到r2,即 r2 等于 pxCurrentTCB stmdb r0!, {r4-r11} (7)//db:decrease before. 以 r0 作为基址(指针先递减,再操作)将 CPU 寄存器 r4~r11 的值存储到任务栈,同时更新 r0 的值 str r0, [r2] (8)//将 r0 的值存储到 r2 指向的内容,r2 等于 pxCurrentTCB。 //到这步结束,上下文切换的上文保存,完成。 stmdb sp!, {r3, r14} (9)//将 R3 和 R14 临时压入堆栈 mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY (10)//将 configMAX_SYSCALL_INTERRUPT_PRIORITY 的值存储到r0 msr basepri, r0 (11)//关中断(???)将r0的值到特殊功能寄存器basepri d*** //数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令 i*** //指令同步隔离 bl vTaskSwitchContext (12)//跳转到vTaskSwitchContext的地址,即执行该函数, mov r0, #0 (13)//退出临界段,开中断,直接往 r0 写 0 msr basepri, r0 //再将r0中的0写入到basepri中 ldmia sp!, {r3, r14} (14)//将多个字从存储器加载到 CPU 寄存器,先操作,指针在递增:从主堆栈中恢复寄存器 r3 和 r14 的值,此时的 sp 使用的是 MSP ldr r1, [r3] (15)//加载 r3 指向的内容到 r1。r3 存放的是 pxCurrentTCB 的地址,即 让 r1 等于 pxCurrentTCB。pxCurrentTCB 在上面的 vTaskSwitchContext 函数中被更新,指向了下一个将要运行的任务的 TCB。 ldr r0, [r1] (16)//加载 r1 指向的内容到 r0,即下一个要运行的任务的栈顶指针 ldmia r0!, {r4-r11} (17)//以 r0 作为基地址(先取值,再递增指针,LDMIA 的 IA 表示Increase After),将下一个要运行的任务的任务栈的内容加载到 CPU 寄存器 r4~r11。 msr psp, r0 (18)//将r0的值写到psp中:更新 psp 的值,等下异常退出时,会以 psp 作为基地址,将任务栈中剩下的内容自动加载到 CPU 寄存器 i*** //指令同步隔离 bx r14 (19)//直接跳转到由寄存器r14给定的地址 nop //NOP空操作伪指令 } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1870 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1657 浏览 1 评论
1137 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
757 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1719 浏览 2 评论
1963浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
786浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
608浏览 3评论
628浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
589浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-9 22:19 , Processed in 0.955018 second(s), Total 75, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号