如何在汇编语言(MIPS)中实现小于或等于? [英] How to do less than or equal in Assembly Language(MIPS)?

查看:15
本文介绍了如何在汇编语言(MIPS)中实现小于或等于?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面前有一个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

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

推荐答案

照常询问编译器(例如on the Godbolt compiler explorer)。另请参阅How to remove "noise" from GCC/clang assembly output?


<=单独(无增量)最好使用颠倒的slt(与a<=b相反的TOb<a)实现,然后然后xori翻转结果。

int booleanize_le(int y, int z){
    return (z<=y);
}
# GCC5.4 -O3 -fno-delayed-branch
booleanize_le(int, int):
        slt     $2,$4,$5        # slt retval, y, z
        xori    $2,$2,0x1       # !retval, i.e. flip 0 <-> 1 since it was already boolean
        j       $31                       # return
  # (omitting the NOP in the branch-delay slot)
有趣的事实:clang for RISC-V做同样的事情,SLT/XORI,因为RISC-V类似于MIPS,只提供sltfor Compare-Into-Boolean。(因为您可以将任何关系(如==、<;=、>;等)布尔化为最多包含2条指令的整数寄存器。)


但是在您想要递增的情况下,并且您使用的是addi,因此很明显z必须是带符号的int(否则您的代码将在从0x7fffffffU到0x80000000U的递增时出错;如果您想要定义良好的回绕,请使用addiu)。

签名溢出的未定义行为的C规则基本上与MIPSaddi的使用相匹配,这意味着编译器也将假定++z没有换行,并进行我们想要的优化。他们和我们,我们可以只使用原始的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链接)。

这篇关于如何在汇编语言(MIPS)中实现小于或等于?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆