ARMv7-A架构是32位处理器架构。也是load/store架构,即数据处理指令操作在通用寄存器完成,只有load/store指令可以访问内存。此外ARM指令集还有一大特点,就是ARM指令集几乎所有的指令都可以增加条件码。
ARM指令集可以归为一下四类:
本文重点介绍协处理器指令。
ARM体系架构支持协处理器,用于扩展ARM处理器功能。协处理器指令用于访问协处理器。协处理器支持16个协处理器,编号0-15,使用CP0-CP15(Coprocessor)描述。
CP0-CP15协处理器的基本功能如下:
关于协处理器详细介绍请参看《ARM体系架构—ARMv7-A协处理器》。
ARM指令集提供了协处理器指令用于访问协处理器中的寄存器。如果协处理器指令访问协处理器在系统中不存在,则会报未定义指令异常(Undef)。
协处理指令可以分为5类:
同时也支持多寄存器指令:
MCRR指令格式如下。
MRRC指令格式如下。
看懂Linux Kernel ARM体系协处理器指令,才能做到学以致用。截取Linux Kernel5.6.4中ARMv7获取PGD(PGD即对应一级页表)的代码:
#ifdef CONFIG_ARM_LPAE /* 定义LPAE,系统物理地址寻址范围扩展到40bit */
#define cpu_get_ttbr(nr) \
({ \
u64 ttbr; \
__asm__("mrrc p15, " #nr ", %Q0, %R0, c2" \
: "=r" (ttbr)); \
ttbr; \
})
#define cpu_get_pgd() \
({ \
u64 pg = cpu_get_ttbr(0); \
pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \
(pgd_t *)phys_to_virt(pg); \
})
#else /* 未定义LPAE,系统物理地址寻址范围是32bit */
#define cpu_get_pgd() \
({ \
unsigned long pg; \
__asm__("mrc p15, 0, %0, c2, c0, 0" \
: "=r" (pg) : : "cc"); \
pg &= ~0x3fff; \
(pgd_t *)phys_to_virt(pg); \
})
#endif
没有开启LPAE的情况,内联汇编语法“%0”引用输出参数pg,变量pg被“=r”限定为存储在寄存器中。
汇编语法“mrc p15, 0, %0, c2, c0, 0”在读取协处理器CP15中c2寄存器。
按照协处理器寄存器的32bit组织形式解析该汇编所访问的寄存器。
CP15协处理器保护c0-c15共16个寄存器,寄存器32位的组织形式如下:
- CRn:第一个协处理器寄存器;
- opc1:协处理器操作码;
- CRm:第二个协处理器寄存器;
- opc2:协处理器操作码。
对于32bit协处理器寄存器的访问,汇编代码解析结果如下:
由32bit寄存器对应图可以看出读取的是TTBR0寄存器,即将页表基址寄存器读取到pg变量中。
开启LPAE的情况,内联汇编语法“%Q0”引用输出参数ttbr,变量ttbr被“=r”限定为存储在寄存器中。
汇编语法“mrrc p15, 0, %Q0, %R0, c2”在读取协处理器CP15中c2寄存器,此时c2寄存器是64bit的。
按照协处理器寄存器的64bit组织形式解析该汇编所访问的寄存器。
寄存器64位的组织形式如下:
- opc1:协处理器操作码;
- CRm:协处理器寄存器;
对于64bit协处理器寄存器的访问,汇编代码解析结果如下:
由64bit寄存器对应图图可以看出读取的是TTBR0寄存器,即将页表基址寄存器读取到ttbr变量中。
本文地址:https://blog.csdn.net/liyuewuwunaile/article/details/107448059
如对本文有疑问, 点击进行留言回复!!
Unity UGUI 之 实现按钮 Button 长按和双击的功能效果
[U3D Learning Note] Unity C# Surival Guide (1) -- Quick Tips and Assets
网友评论