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

xdnvmnnf  于 2022-11-24  发布在  其他
关注(0)|答案(2)|浏览(138)

我写逻辑AND语句的方式是否与写逻辑OR语句将C转换为mips程序集的方式相同?

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

这是我写的

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

xghobddn1#

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

rkue9o1l

rkue9o1l2#

我们将根据需要使用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:
        ...

通过对&&的操作数取反并更改为||,可以在合取中分配取反。
德·摩尔根对否定条件的应用:

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

而且这两条线很容易组装。
作为另一种方法,我们可以将&&转换为&,因此,我们可以计算两个操作数,并简单地将结果一起计算and,然后使用单个分支指令进行测试,而不是实现短路运算符。而X1 M5 N1 X可以用X1 M6 N1 X代替。
只有在代码允许的情况下,将短路运算符转换为非短路运算符才有效,这意味着程序必须始终执行/执行/计算第二个操作数。函数调用或数组引用不一定可以执行,因为它受到第一个条件的保护。下面是一个示例:当不能转换短路操作器时:

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

数组引用由使用短路运算符的范围检查保护/保护,因此如果将其转换为&,有时会导致数组引用超出边界,无法计算&&的两侧。
第二个操作数中的函数调用对于此转换也可能存在问题。

相关问题