【问题标题】:ARM assembly - simple blinker program refuses to execute part of the codeARM 汇编 - 简单的闪烁程序拒绝执行部分代码
【发布时间】:2018-02-08 21:18:03
【问题描述】:

我正在尝试使 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 代码中运行得非常好……有没有人发现错误,因为我不能。我会以某种方式覆盖寄存器吗?难道是我的编译器以某种方式优化了代码?

【问题讨论】:

  • 汇编器不优化。至少不是 gnu。
  • 你启用了gpio的时钟吗?在没有循环的情况下只尝试其中一个,只需打开即可。然后制作一个刚刚关闭的版本。分别尝试每个(最好没有调试器)。如果你不能强制它打开并保持打开,也不能强制它关闭并保持关闭,那么你就不能眨眼,你可能会因为其他原因而不是你想象的原因看到它。
  • 我想通了!评论弄乱了我的代码!我删除了它们,现在它可以工作了......什么!???
  • a) 删除或自行回答。 b) 查看 lst 文件(程序集的转储文件),看看你的好代码和坏代码是如何呈现的。
  • 在使用和不使用 cmets 的情况下,您的反汇编显示了什么?它是否与您的代码匹配(至少在某种程度上您的 ldr =0x... 导致 mov 或 pc 相对负载与池数据。

标签: gcc assembly arm lpc


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多