本帖最后由 andeyqi 于 2024-11-16 14:00 编辑
简介 工作中ARM 芯片开发我们或多或少都会接触到ARMV7-M指令集,本地使用IAR 环境来学习Cortex M4/M7 处理器对应的常用指令集
ADR指令(ARMV7-M): ADR 指令是一条小范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中。对应的指令说明如下及编码规则说明如下: add 的条件TRUE/FALSE 有T1/T2/T3三种编码格式,我们添加如下汇编代码验证ADR指令。 asm_test_stm:
ldmia r0, {r1-r3}
mov r1, #1
mov r2, #2
mov r3, #3
stmia r0, {r1-r3}
bx lr
asm_test_ldr_adr:
adr r0,asm_test_stm
ldr r1,=xIsPrivileged
adr r2,xIsPrivileged -1
bx lr
xIsPrivileged:
mrs r0, control /* r0 = CONTROL. */
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
itt ne
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
movne r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
bx lr /* Return. */
Debug 运行发现 第一条的adr r0,asm_test_stm 指令被编译器编译为ADR.W 指令对应的机器码为0xf2af 0x0019
因为是向前跳转add 是false 按照指令编码decode 解析可知。
对应 i = 0,imm3 = 0,imm8 = 0x19,按照如下的指令解码规则。
R0 = Aligin(PC,4) - Imm32; Aligin(PC,4) 的计算说明如下:
当前PC 值为0x0801 2700 向上按照4字节对齐 Aligin(PC,4) = 0x0801 2704, imm32 = 0x19 R0 = 0x0801 2704 - 0x19 = 0x0801 26EB 跟如下的执行结果一致,该指令会根据当前PC指针的值减去offset 计算出相对PC指针的地址。
add = TRUE 的场景也是类似,按照编码格式解析出add 条件及offset 从而根据PC值计算出对应的符号的相对PC的地址 ADR指令(ARMV6-M): ARMV6-M 的ADR 编码格式相对 ARMV7-M 只有T1 这一种编码格式。
在 ARMV6-M的芯片上对应的编码使用的ADR.N 对应T1 的16bit 的编码格式。
|