1. aarch64 == A64 == ARM 64位架构 != cortex A64, A64 涵盖 cortex A64 还包括 cortex A53,cortex A35等
2. Embedded processors 基于 ARMv7 和 ARMv8 版本下 R/M 系列的 cortex-R/M 架构设计处理器,比如ARMv7M的cortex-M3的stm32f1/4/7
3. A-profile processors 指基于 ARMv7 和 ARMv8 版本下 A 系列的 cortex-A 架构设计的处理器,比如ARMv8A的cortex-A53的全志h618
参阅 https://www.cnblogs.com/solo666/p/16405064.html
4. ARM processors are typical of RISC processors in that only load and store instructions can access memory(SRAM).
Data processing instructions operate on cpu register contents only.
5. ARMv7-M only supports the Thumb instruction set. Therefore, interworking instructions in ARMv7-M must not attempt to change to ARM state. So ARMv7-M'xPSR bit24 === 1.
Thumb instructions both have 32-bit and 16-bit width, all ARM instructions are 32 bit width.
6. The processor modes available in ARMv6-M and ARMv7-M are only Thread mode and Handler mode.
Thread mode is the normal mode that programs run in. Thread mode can be privileged or unprivileged software execution.
Handler mode is the mode that exceptions are handled in. It is always privileged software execution.
7. armcc编译器的关键字 AREA 等同于 gcc编译器的关键字 .section,都是用来指定一个段
AREA RESET, DATA, READONLY 和 .section .isr_vector,"a",%progbits 都是用来定义段和段的属性;
8. arm 使用特殊的返回指令来区分中断返回和函数调用返回,如果LR的值是0xFFFFFFF1,0xFFFFFFF9,0xFFFFFFFD就表示从irq中返回,如果是一般的指令地址值就表示从call返回。
如果主程序在线程模式下运行,并且在使用MSP时被中断,则在服务例程执行期间LR=0xFFFF_FFF9(主程序被打断前的LR已被自动入栈);
如果主程序在线程模式下运行,并且在使用PSP时被中断,则在服务例程执行期间LR=0xFFFF_FFFD(主程序被打断前的LR已被自动入栈)。
当ISR在嵌套时LR的值总是0xFFFF_FFF1,同理若LR的值是0xFFFF_FFF1就表明当前isr在嵌套。
9. cortex-M3/4架构下往 r0 中放一个 32bit 的立即数0x20001384,需要分2步即
10. ARM和Thumb指令集都包含一个基本的子程序调用指令BL,它执行带有链接的分支操作。执行BL的效果是将程序计数器的下一个值(返回地址)转移到链接寄存器(LR)中,并将目的地址转移到程序计数器(PC)中。如果从Thumb状态执行BL指令,链路寄存器的0位将设置为1,如果从ARM状态执行,则设置为0。通过 BL subfun 进入子函数,通过 BX LR 或 POP {PC} 退出子函数; 因为退出时需要将LR的值传给PC,故在进入时需要根据状态设置LR的bit0。
11. 对于主调方,假定在封送处理之前已经分配了足够的堆栈空间来容纳堆叠的各参数,直到完成参数封送处理之后才能知道参数所使用的堆栈空间量。被调用方可以访问和修改用于从主调方接收参数值的任何堆栈空间。
12.
汇编 b.n 的说明:这条指令的作用是无条件跳转,n并非指xPSR中的负数标志。这里.n和.w是一组,用于指定机器码是窄的16bit/宽的32bit。
xPSR中用于构成跳转和条件判断的组合一共就只有15种,分别是EQ,NE,CS/HS,CC/LO,MI,PL,VS,VC,HI,LS,GE,LT,GT,LE和AL。
13. BL 指令:主调函数通过 bl 调用子函数 Board_Init,在执行 bl 的一瞬间 pc = 8000f48, lr = 8000432+1, 然后切换到子函数 Board_Init 的入口地址 8000f48 处,之后 push {r7, lr} 时 lr 的值是 8000433 而不是主函数调用子函数时在执行 bl 指令前的lr的值,所以压栈值是8000433和0.
14. ARMv7-M架构下 LR 寄存器的说明:(1)LR的值如果是0xFFFFFFF9/0xFFFFFFFD则表示处于中断/异常处理的本体函数中(批注:从进入isr的一刻起到发生中断内调用子函数之前,lr的是0xFFFFFFF9/0xFFFFFFFD,一旦发生调用再返回到isr之后,lr的值就不是0xFFFFFFF9/0xFFFFFFFD,而是0x08开头的地址,中断嵌套也是同理);如果是0xFFFFFFF1则表示处于中断/异常嵌套处理中;如果是0x08开头则表示处于子程序调用中,既包括用户模式下函数间的调用也包括中断本体函数对其子函数的调用。(2)LR值如果是0xFFFFFFF9则从msp出/入栈,如果是0xFFFFFFFD则从psp出/入栈。(3)thread模式下由control寄存器的bit0决定是特权级还是用户级。
15. R0-R3负责传参和保存返回值,主调函数在调用子函数时要先将R0-R3中有效的值提前push存入ram中,之后将参数写入R0-R3中,再BL subfun,在subfun中立即对sp执行自减操作,以容纳subfun的栈变量和传参。sp按8字节对齐,即分配一/两个栈变量都是 sp-=8
16. 被调函数的栈变量和传参都是在被调函数的栈空间上分配的,而不是之前理解的传参在主调函数的栈空间分配。虽然主调函数和被调函数的栈空间是线性连续的。被调函数退出前会将返回值写入到R0-R3中覆盖之前的传参值。而R4-R11则由被调函数维护,在被调函数中需要将用到的R4-R11先push,后使用,再在被调函数退出前pop。4个以内的参数传递由r0-r3负责,但对参数值的访问必须通过sp,而不能直接从r0-r3中读取(因为中断)。多于4个参数时会将左侧4个参数通过r0-r3传递,其余的传参通过直接操作sp传递。
17. 包括isr在内的所有函数入口都会有第一、三行的汇编,第二行的存在取决于函数是否有局部变量和传参,第三行的作用是在整个函数体内都用R7代替sp访问局部变量和参数,这样可以保证函数体内sp值的固定不变,同时结尾会mov sp, r7 和 pop R7, 这样就保证了函数进入前瞬间和退出后瞬间sp的值是相等的。只要在isr内部不调用子函数那么lr在isr推出前就一直是0xFFFFFFF9/0xFFFFFFFD,如果中途调用过子函数那么lr就是0x08开头的值;同时因为有子函数调用的isr会在入口处push lr,这样在退出时pop pc就会把异常返回序列传到pc中,实现异常的退出。
18.单线程或裸机程序,在函数调用前一刻和调用结束后一刻sp的值必然是相等的,其他寄存器不保证;同理在中断进入前一刻和中断退出后一刻sp的值也必然是相等的;多线程切换时sp的值就会变。