assembly 如何在汇编语言(MIPS)中实现小于或等于?

lymgl2op  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(110)

我面前有C代码,我必须将其翻译成MIPS汇编语言。
我并不寻求直接的答案,但我希望有人能纠正我思考这个问题的方式。
我面前的C代码是:

x = ((++z) <= y);

字符串
在给定的情况下,x、y和z分别存储在寄存器 $6、$7、$8 中。
问题是我不能使用运算符直接比较小于或等于。我只能使用以下比较操作数:bne,beq,ori,slt.
我处理这个问题的方法是这样的:

addi   $8,$8,1     # This will increment z by 1 to have ++z
      slt    $1,$8,$7    # Compares ++z to y if ++z is < than y. It
                         # will store 1 in $1
      beq    $8,$7,Label # Compares if $8 = $7. If so, the code
                         # jumps to Label
Label addi   $t0,$0,1    # If ++z = y, stores 1 in $t0
      ori    $6,$t0,$1   # Or's the t0 and t1 and accordingly stores
                         # 0 or 1 in x


这是解决这个问题的正确方法吗?

wfveoks0

wfveoks01#

像往常一样,询问编译器(例如Godbolt编译器资源管理器上)。参见How to remove "noise" from GCC/clang assembly output?

<=单独(没有增量)最好使用反向slt(执行与a<=b相反的b<a)和**然后xori**来翻转结果。

int booleanize_le(int y, int z){
    return (z<=y);
}

个字符
有趣的事实:RISC-V的clang做了同样的事情,slt/xori,因为RISC-V就像MIPS一样,只提供slt用于比较到布尔值。(因为你可以用最多2条指令将任何关系,如==、<=、>或其他任何关系布尔化到整数寄存器中。
但是在你想要递增的情况下,你使用的是addi,所以很明显z必须是一个有符号的int(否则你的代码在从0x 7 fffffffU递增到0x 80000000 U时会出错;使用addiu,如果你想要良好定义的环绕)。

**针对signed-overflow的C规则基本上与MIPS addi的使用相匹配,这意味着编译器也会假设++z没有 Package **,并进行我们想要的优化。他们和我们我们可以只使用原始的z值。如果z+1不能换行,则(z+1)<=yz<y是一样的。

int booleanize_inc_le_signed(int y, int z){
    return ((++z)<=y);
}
booleanize_inc_le_signed(int, int):
        slt     $2,$5,$4             # z<y  before incrementing
        j       $31
    # increment optimized away in this function, but you'd do it with
    addiu   $5, $5, 1

的字符串
如果z是无符号的,那么这种优化是不可能的,编译器只是递增,然后使用2指令<= slt/xori序列的无符号版本:

int booleanize_inc_le_unsigned(unsigned int y, unsigned int z){
    return ((++z)<=y);
}
booleanize_inc_le_unsigned(unsigned int, unsigned int):
        addiu   $5,$5,1                # z++
        sltu    $2,$4,$5               # y<z (unsigned)
        xori    $2,$2,0x1              # return !(y<z)
        j       $31

的字符串

其他关系

完全相等,a == b

xor     $2,$4,$5          # find bit-differences
    sltu    $2,$2,1           # (a^b) < 1U

不相等,a != b

xor     $2,$4,$5
    sltu    $2,$0,$2          # 0U < (a^b)

一个非零整数:a!=0,即!!a

sltu    $2,$0,$4          # 0U < a


任何其他的显然都可以派生,或者只需要询问编译器(使用Godbolt链接)。

相关问题