引用来自汇编器的C指针

问题描述

我想在汇编器函数中引用c指针。在C中的声明如下:

const uint32_t * SERCOM0_SPI_DATA_REG_ADDR =(易失性uint32_t *)&(SERCOM0-> SPI.DATA.reg); // uint32_t reg;

在组装中,指针地址(0x40003028)正确显示在调试器中。使用以下代码,我想将值0x1f写入到uint32_t的spi寄存器中。

// reg uint32_t sercom spi data
    ldr r0,=SERCOM0_SPI_DATA_REG_ADDR
    ldrb r1,=#0x1f
    str r1,[r0]  

如果我现在查看寄存器r0,则该值不是0x40003028,而是0x20000F8C。因此,在该地址处未写入0x1f值。

在反汇编窗口中:

    44:     ldr r0,=SERCOM0_SPI_DATA_REG_ADDR
00007804   ldr  r0,[pc,#28]        
    45:     ldrb r1,= #0x1f // SERCOM0_SPI_DATA_SYNC_DATA
00007806   mov.w    r1,#31      
    46:     str r1,[r0]  

assem文件如下:

.section .ram
.Syntax unified
.cpu cortex-m4
.thumb

.space 0xe4
.data
.text
.align 4

.type SEND_DATA,%function
.global SEND_DATA

VUSB_SEND_DATA:
...
bx lr

解决方法

回想一下,汇编中的符号是它们表示的变量的地址。所以

ldr r0,=SERCOM0_SPI_DATA_REG_ADDR

r0的地址装入SERCOM0_SPI_DATA_REG_ADDR,大致等于

r0 = &SERCOM0_SPI_DATA_REG_ADDR;

要加载该变量的 value ,您需要取消引用刚获得的指针:

ldr r0,=SERCOM0_SPI_DATA_REG_ADDR    @ load address of variable
ldr r0,[r0]                          @ load value of variable

将此与您剩余的代码结合起来,可以解决您的问题。请注意,为获得更好的代码大小,建议在拇指目标上加载小常量时明确使用movs

ldr r0,=SERCOM0_SPI_DATA_REG_ADDR
ldr r0,[r0]
movs r1,#0x1f
str r1,[r0]

这应该产生预期的结果。