【问题标题】:MIPS bne assembly instruction not executing correctly under Microchip XC32 [duplicate]MIPS bne 汇编指令在 Microchip XC32 下无法正确执行 [重复]
【发布时间】:2021-11-29 20:00:36
【问题描述】:

所以我在一个使用 XC32 的 MPLABX 项目中编译了以下代码,目的是检查我是否需要更改 RTOS 实现的上下文:

    .extern OS_TaskRUNNING, 0x04 # Both of these are pointers in a C file
    .extern OS_TaskNEW, 0x04

CheckSwitch:
    la $1, OS_TaskRUNNING
    la $2, OS_TaskNEW
    lw $1, 0x00($1)
    lw $2, 0x00($2)
    xor $1, $1, $2
    bne $1, $0, ConfirmSwitch
AbortSwitch:
    # stuff happens...
ConfirmSwitch:
    # stuff happens...

当两个指针中的值不同时,程序执行无法跳转到 ConfirmSwitch,而是继续执行到 AbortSwitch(注意非常细心的人:我在此文件中的代码中使用了 'noat' 设置) .无论价值以 1 美元和 2 美元结束,分支永远不会发生。我尝试了其他变体,例如 bne $1, $2, ConfirmSwitch 并最终得到相同的结果。我不知道我可能做错了什么,因为这个功能太基础了。

【问题讨论】:

  • 这个 MIPS 有分支延迟槽吗?您可以尝试在bne 之后添加nop
  • 您是否在调试器(或模拟器)中单步执行代码以查看寄存器中的值?并查看执行的确切路径,包括可能的分支延迟槽,以防万一你认为 AbortSwitch 正在运行。 (如果 xc32 是 MIPS32r6,您可以使用新的 no-branch-delay 分支指令。)

标签: assembly mips xc32


【解决方案1】:

根据下面的 cmets 计算出来;在每个分支指令后添加一个 nop 解决了这个问题。在模拟器中,无论分支条件是否为真,执行都会转到 nop,但随后会转到正确的位置。顺便说一句,我还使用了“noreorder”指令来阻止汇编程序重新组织我的代码。 XC32 汇编器手册在提到上述指令时讨论了分支延迟槽:“默认情况下,汇编器尝试通过以下方式自动填充分支或延迟槽 重新排序它周围的指令。”这是整个手册中唯一真正提到延迟槽的地方——没有讨论什么分支指令需要这些或它们可能需要多大。我在网上找到了许多示例代码示例来研究这个问题甚至不提这件事。

【讨论】:

  • 许多 MIPS 代码是为没有分支延迟槽的假的或简化的 MIPS 编写的,例如默认情况下模拟 MARS / SPIM(或者我猜是 reorder 模式)。 MIPS 的分支延迟槽是基本 MIPS ISA 的一个特性,而不是你的汇编程序正在做的事情。
  • 如果您不了解延迟槽,请参阅devblogs.microsoft.com/oldnewthing/20180411-00/?p=98485。和/或不使用noreorder 选项,因此您可以编写忽略分支延迟槽的代码,并让汇编器用独立指令或NOP 填充它。如果您不理解它们,请不要使用noreorder 汇编程序选项!汇编器文档作者假设知道分支槽的人将是使用noreorder 的人是有道理的,否则汇编器会隐藏它们的存在,因此他们不能提及它们。
猜你喜欢
  • 2012-01-10
  • 2012-01-09
  • 1970-01-01
  • 2014-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
相关资源
最近更新 更多