这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【GCC】汇编代码.ltorg使用整理

共1条 1/1 1 跳转至

【GCC】汇编代码.ltorg使用整理

高工
2025-11-05 16:52:16     打赏

【简介】

今天在查看以下,基于GCC 的FreeRtos 的适配代码中发现了 .ltorg  的指令,对于该指令不是很了解其意义。

static void prvPortStartFirstTask( void )
{
    /* Start the first task.  This also clears the bit that indicates the FPU is
     * in use in case the FPU was used before the scheduler was started - which
     * would otherwise result in the unnecessary leaving of space in the SVC stack
     * for lazy saving of FPU registers. */
    __asm volatile (
        " ldr r0, =0xE000ED08   \n"/* Use the NVIC offset register to locate the stack. */
        " ldr r0, [r0]          \n"
        " ldr r0, [r0]          \n"
        " msr msp, r0           \n"/* Set the msp back to the start of the stack. */
        " mov r0, #0            \n"/* Clear the bit that indicates the FPU is in use, see comment above. */
        " msr control, r0       \n"
        " cpsie i               \n"/* Globally enable interrupts. */
        " cpsie f               \n"
        " dsb                   \n"
        " isb                   \n"
        " svc 0                 \n"/* System call to start first task. */
        " nop                   \n"
        " .ltorg                \n"
        );
}

查看了下GNU 的手册 对 ltorg 的描述如下:

image.png

.ltorg 是 GNU 汇编器(GAS)针对 ARM/Thumb 架构的伪指令,用来在当前位置生成一个“字面常量池”(literal pool)。当汇编代码中使用了 ldr r0, =0xE000ED08 这类“伪指令”装载常量时,真实做法是在附近放置常量数据,再用 PC 相对地址跳过去取;.ltorg 会强制把这些待生成的常量立即写到当前位置,从而刷新常量池。这样做能避免常量池距离当前指令过远导致 PC 相对寻址超出范围,也常作为函数末尾的规范写法,确保所有字面量都已落在可到达范围内。

上述内嵌汇编的代码编译后的代码如下:

 005041D0   LDR            R0, =VTOR_REG                 ; [PC, #32] [0x005041F4] =0xE000ED08 
 005041D2   LDR            R0, [R0]
 005041D4   LDR            R0, [R0]
 005041D6   MSR            MSP, R0
 005041DA   MOV.W          R0, #0
 005041DE   MSR            CONTROL, R0
 005041E2   CPSIE          i
 005041E4   CPSIE          f
 005041E6   DSB            SY
 005041EA   ISB            SY
 005041EE   SVC            #0
 005041F0   NOP
$Data
 005041F2   DC16           0x0000
$Data
 005041F4   DC32           0xE000ED08                    ; VTOR_REG

查看对应的对应的汇编代码也可以看出,在NOP 指令的后面放置了一个文字池来加载数据至R0寄存器。

本地修改代码删除函数末端的 .ltorg 

image.png

修改后的编译器产生的代码,在函数的末端没有添加literal pool 而是放到如下地址。

image.png


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]