如何编写多个条件if else语句mips

问题描述 投票:0回答:2

我会像编写将 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
2个回答
2
投票

我们将根据需要使用 deMorgan 进行转换:

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

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

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

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

可以通过对

&&
的操作数求反并更改为
||
,将否定分布在合取上。

德摩根在否定条件上的应用:

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

然后优化关系的否定:

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

这可以分为两个 if 语句:

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

这两条线很容易组装。


我们可以将

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

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

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

数组引用受到使用短路运算符的范围检查的保护/保护,因此,如果将其转换为

&&
,有时会导致数组引用越界来评估
&
的两侧。

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


以 || 开头时连接词如:

...
if ( c < 'a' || c > 'z' ) {
    <then-part>
}
else {
    <else-part>
}
...

首先转换为if-goto-label形式:

        ...
        if ( ! ( c < 'a' || c > 'z' ) goto elsePart1;
    thenPart1:
        <then-part>
        goto endIf1;
    elsePart1:
        <else-part>
    endIf1:
        ...

DeMorgan,这个否定变成:

        if ( ! ( c < 'a' ) && ! ( c > 'z' ) ) goto elsePart1;

通过颠倒关系:

        if ( c >= 'a' && c <= 'z' ) goto elsePart1;

接下来,我们可以将复合 && if 语句拆分为两个 if 语句,通过调整目标并再次求反,这次只是其中的一半:

        if ( c < 'a' ) goto thenPart1; 
        if ( c <= 'z' ) goto elsePart1;
    thenPart1:
        <then-part>
        goto endIf1;
    elsePart1:
        <else-part>
    endIf1;

如您所见,这次我们确实需要

thenPart1:
标签,而在其他转换中我们可能不会使用它。


另请注意,假设没有副作用,我们也可以将 && 转换为 &,就像 || 的转换一样到 |,这消除了复杂的条件。


0
投票

你不小心搞反了你的逻辑。我假设“draw219”是一段相当于您的 C 代码的代码

printf("%c", 219);
bne
指令不应在那里分支,因为它们仅在两个寄存器不相等时才分支。当两个寄存器不相等时,总体
if
条件为 false,因此您应该分支到接下来要执行的任何代码块,但不要转到“draw219”。

© www.soinside.com 2019 - 2024. All rights reserved.