问题描述
我想在汇编器函数中引用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]
这应该产生预期的结果。