ARM 汇编 - 简单的闪烁程序拒绝执行部分代码

ARM assembly - simple blinker program refuses to execute part of the code

我正在尝试使 LPC4088(Datasheet) 上的 LED 闪烁,并且我已经正确准备好外设寄存器。现在是闪烁 LED 的时候了,这是应该执行此操作的循环:

blink:

    @ In register SET1 (0x20098038) we set bits:
    @ bit 13 = 1    >   sets pin P1_13 to high state
    ldr r0, =0x20098038
    ldr r1, [r0]
    ldr r2, =0x2000
    orr r1, r2
    str r1, [r0]

    @ NO DELAY NEEDED FOR DEBUG

    @ In register CLR1 (0x2009803C) we set bits:
    @ bit 13 = 1    >   sets pin P1_13 to low state
    ldr r0, =0x2009803C
    ldr r1, [r0]
    ldr r2, =0x2000
    orr r1, r2
    str r1, [r0]

    @ NO DELAY NEEDED FOR DEBUG

    b blink

当我在调试器中检查代码的执行时,我注意到循环的第一部分(在第一个 @ NO DELAY NEEDED FOR DEBUG 之前)执行良好,并且 LED 在执行命令 str r1, [r0] 时恰好打开。

现在是循环的第二部分(在第一个 @ NO DELAY NEEDED FOR DEBUG 之后),当我尝试执行 ldr r0, =0x2009803C 时,LED 不会关闭。相反,我的程序直接跳转到循环的第一部分,并在下一步中执行 ldr r0, =0x20098038。所以说明:

ldr r1, [r0]
ldr r2, =0x2000
orr r1, r2
str r1, [r0]

循环的第二部分永远不会执行...

此代码以前在 C 代码中运行得非常好...有没有人发现错误,因为我不能。我会以某种方式覆盖寄存器吗?会不会是我的编译器以某种方式优化了代码?

您不能从地址 2009803c 的寄存器 CLR1 读取,因为它是只写的(请参阅用户手册)。结果你得到一个错误(我不确定到底是哪一个,可能是 MemManageFault 或 BusFault)。通常它会跳转到故障处理程序,但从您看到的行为来看,它似乎重新启动了程序。

解决方案不是读取 SETCLR 寄存器,您应该只写入要设置或清除的位模式。