【问题标题】:How to write multiple condition if else statement mips如何编写多个条件 if else 语句 mips
【发布时间】:2022-11-29 09:52:35
【问题描述】:

我会像编写将 C 转换为 mips 程序集的逻辑 OR 语句一样编写逻辑 AND 语句吗?

else if (i == x && j == y)
printf("%c", 219);

这就是我说的

bne $reg1, $t3, draw219 # i==x
bne $reg2, $t4, draw219 # j==y

【问题讨论】:

标签: c assembly mips


【解决方案1】:

我们会根据需要使用 deMorgan 来转换:

结构化 if-then-else 语句中的复合条件:

...
if ( i == x && j == y ) {
    <then-part>
}
else {
    <else-part>
}
...

在 if-goto-label 形式中,条件被否定,同时分支指向 else 部分,所以将这两个更改一起,它仍然运行相同(它实际上是双重否定,所以逻辑相同):

        ...
        if ( ! (i == x && j == y) ) goto else1Part;
    then1Part:
        <then-part>
        goto endIf1;
    else1Part:
        <else-part>
    endIf1:
        ...

通过对&amp;&amp; 的操作数取反并更改为||,可以在合取上分配否定。

de Morgan 对否定条件的应用:

    if ( ! (i == x) || ! (j == y) ) goto else1Part;

然后优化关系的否定:

    if ( i != x || j != y ) goto else1Part;

这可以分为两个 if 语句:

    if ( i != x ) goto else1Part;
    if ( j != y ) goto else1Part;
    // will come here when the original if condition is true

这两条线很容易组装。


我们可以将 &amp;&amp; 转换为 &amp; 作为另一种方法,因此我们可以评估两个操作数并简单地将 and 的结果一起评估,并使用单个分支指令对其进行测试,而不是实施短路运算符。德摩根也可以申请;而 || 可以替换为 |。

将短路运算符转换为等效的非短路运算符只有在代码允许的情况下才有效,这意味着程序必须能够始终执行/执行/评估第二个操作数。如果函数调用或数组引用受到第一个条件的保护,则不一定可以执行。这是一个示例,说明何时不能转换短路运算符:

if ( i < N && a[i] == 0 ) ...

数组引用受到使用短路运算符的范围检查的保护/守卫,因此如果将其转换为&amp;,有时会导致数组引用越界评估&amp;&amp; 的两侧。

第二个操作数中的函数调用对于此转换也可能有问题。

【讨论】:

  • 您实际上可以将其实现为 xor tmp1, i, x / xor tmp2, j, y / or tmp1, tmp1, tmp2 / 然后 bnez 或 beqz 在组合条件下分支一次。 (那些 var 名称是寄存器的占位符)。或者在一个假的/简化的 MIPS 上,你可以将两个分支背靠背放置(没有延迟槽)然后是的,也许你只是这样做,特别是因为存在两个非零寄存器之间的 beq 和 bne 。
  • @PeterCordes,是的,MIPS 没有seq 或sne(只有slt),所以xor 方法很好!
  • xor 或 subu 获得 0 / 非零是一种有点标准的技术,例如作为编译器如何在没有标志的 ISA 上使用 xor/sltu 实现 int cond = (x != y) 或 x == y 的一部分。 (How to do less than or equal in Assembly Language(MIPS)?)。有时对 SIMD 也很有用。
【解决方案2】:

你不小心颠倒了你的逻辑。我假设“draw219”是一段等同于您的 C 代码 printf("%c", 219); 的代码。 bne 指令不应该在那里分支,因为它们只有在两个寄存器不相等时才会分支。当两个寄存器不相等时,整个if条件为假,所以你应该跳转到接下来要执行的任何代码块,但不要转到“draw219”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    相关资源
    最近更新 更多