除了通用寄存器,就是系统寄存器了 , 按照访问指令 将其分类
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 编译器应该默认不支持硬件浮点,而其他架构的编译器应该支持硬件浮点
但是我看了一下编译器(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
|