LDR与LDR伪指令解析与使用场景

 下面是freertos源码中使用LDR命令一些场景

LDR指令使用场景1:

/*ulPortInterruptNestingConst = ulPortInterruptNestingConst +1*/

LDR r3, ulPortInterruptNestingConst    /*获取ulPortInterruptNestingConst位置的内容,即ulPortInterruptNesting变量对应的地址。所以如果访问ulPortInterruptNesting,需要LDR r1, [r3] 才会将ulPortInterruptNesting的内容加载到r1寄存器*/
LDR r1, [r3]
ADD r4, r1, #1
STR r4, [r3]

ulPortInterruptNestingConst: .word ulPortInterruptNesting

uint32_t ulPortInterruptNesting = 0UL; //此变量在某个c文件中定义

LDR指令使用场景2:

/* Call the interrupt handler. */
PUSH {r0-r4, lr}
LDR r1, vApplicationIRQHandlerConst  /*获取vApplicationIRQHandlerConst位置的内容,即HwiP_irq_handler_c,因为HwiP_irq_handler_c本身就是一个中断处理函数地址,所有能够使用 blx r1直接跳转到函数地址*/
BLX r1
POP {r0-r4, lr}
ADD sp, sp, r2

vApplicationIRQHandlerConst: .word HwiP_irq_handler_c

void __attribute__((section(".text.hwi"))) HwiP_irq_handler_c(void)  // 此中断处理函数在c文件中定义
{
....
}
 

LDR伪指令主要有两种用途:

‌1.加载32位常量到寄存器‌:LDR R0, =0x1234ABCD ; 将32位立即数加载到R0,汇编器会自动将该指令转换为合适的MOVPC相对加载指令。

‌2.加载标号地址‌:LDR R1, =data_label ; 将编译器给这个data_label标号的地址加载到R1

 总结

1.使用.word 关键字 分别将ulPortInterruptNesting的地址,以及HwiP_irq_handler_c(本身就是地址)按顺序放到特定位置
2. 另外一点ulPortInterruptNesting本身是不是指针都没有影响。如果ulPortInterruptNesting变量是一个指针,那么我要访问指针所指向的内容,应该怎么写:

LDR r1, [r3]  /*这条指令将ulPortInterruptNesting指针本身的内容放入r1中*/

LDR r2, [r1] /*那么这条指令就是ulPortInterruptNesting指针指向的内容放入r2,即*ulPortInterruptNesting */

LDR r3, [r2] /*如果ulPortInterruptNesting是一个二级指针,那么现在r3中的内容就是**ulPortInterruptNesting */

以此类推 n级指针都可以访问

 

posted @ 2025-08-11 19:25  songchaohuang  阅读(21)  评论(0)    收藏  举报