拼接宏(##)不能拼接 '('
有时候 2 ,有时候 4 , 异常返回时减去了吗?2还是减去4
arm64 的 在编程异常向量表时,注意范围不得超过范围 0x80 其他的 像 arm32 ,虽然 也是异常向量表,但是只有0x4, 很好避免 其他的 像 rv ,也是 0x4 , 也可以 单入口
除通用寄存器外,是系统寄存器 , 根据访问指令 将其分类 arm32 有两种系统寄存器 : PSR(CPSR/SPSR)(用MRS读/MSR写访问) & Copr寄存器(用MRC读/MCR写访问) arm64 一类 : (用MRS读/MSR写访问) rv 一类 : (用csrr读/csrw写访问)
对于 所有架构,并非所有的寄存器都是读写的。 有时写入会导致清除,有时会出现异常,有时候未知(TODO)
arm32 和 rv32 可以 使用两个寄存器 来保存 uint64_t 从而来做 64位 运算 但是 printf("%llx\n",data); 无法打印 uint64_t data
arm32的助记符 一般可以在 arm64中用 但是arm64中没有cp15(即没有mrc和mcr指令), 增加了 许多系统寄存器 arm64 也增加了 一些load store 相关的指令,所以有更多的指令助记符
基本上,一套汇编代码可以兼容rv32和rv64 只需编译不同的编译选项 但是反汇编的东西在某些地方是不同的,因为rv32和rv64指令集不完全兼容
- arm32/arm64/rv对待初始化 栈中的数组 为 0 的区别
arm32/rv 引用了 memset ,arm64没有引用 arm64 用 stp xzr, xzr, [sp, #16] 来填充0
arm32 需要 __aeabi_uidivmod 和 __aeabi_uidiv 支持去除法 为什么呢? 因为arm32上 定点除法指令 是 可选的 所以有三种情况 1. 硬件上有(取决于CP15 ID_ISAR0 Divide_instrs, bits[27:24])定点除法指令,编译器(用-mpu=cortex-a15/-mcpu=cortex-a7)编译出了除法指令
2. 硬件上有定点除法指令,编译器支持但是没有编译出除法指令
3. 硬件上没有定点除法指令,编译器不支持且没有编译出除法指令
其他架构的编译器默认会编译为定点除法指令
查看 https://blog.csdn.net/u011011827/article/details/124159285 看更多
查看 https://qa.1r1g.com/sf/ask/1104746261/ 看更多
---------------- 以下是浮点除法,和 我说的定点除法没关系
arm32 编译器应该默认不支持硬件浮点,而其他架构的编译器应该支持硬件浮点
但是我看了一下编译器(arm-linux-gnueabihf-gcc -Q --help=target)默认支持 硬件浮点,且用浮点寄存器传参
1. -mfloat-abi= hard // 支持 硬件浮点,且用浮点寄存器传参
2. -mfpu= vfpv3-d16 // 浮点扩展 硬件版本
但是不知道为什么编译出来的汇编指令还是没有用到"浮点寄存器"和"浮点指令"
1. 都有异常向量表,一个特权级一张表
2. rv 可以单入口, 但是arm32/arm64不行.相较于arm64,arm32的入口更多
3. 狭义异常的判断 , mcause和mepc(rv) , (ifsr,fsr 和 ifar,far 位于cpu15寄存器)arm32, (esr,far)arm64
一个是异常原因,一个是异常地址
4. 狭义中断的判断 , mcause和plic(rv) , (gic)arm32和arm64
5. 狭义异常需要通过设置pc清除
6. 狭义中断;如果是电平触发,需要控中断控制器清除;如果是边沿触发,不需要清除;
7. arm32的异常向量表基址(在不开secure的情况下)只能二选一 , 而其他的架构是可以设置的
8. arm32的第一条指令之后必须属于是异常向量表?如果基址可以指定的话,其实可以第一条指令可以不属于异常向量表,可以连续执行指令.在恰当的时候设置基址,并在该地址填充异常向量表就行了.
9. arm32的异常入口相当多, 在你不熟悉的情况下,很难区分某个异常进入哪个入口.
arm32/arm64 每个特权级都有独立的sp寄存器,arm32甚至每一个运行模式都有一个.
rv只有一个sp寄存器
所以rv在 硬件切换特权级后,第一件事,就是 设置 sp
在 切换前,就是保存sp