汇编:比较返回与预期结果相反的结果

时间:2014-06-08 11:36:27

标签: assembly conditional-statements x86-64

我必须对某种编译器进行编码,它的工作方式非常好,但是我的语义是" is-greater-than"表达

例如,我想返回最小的参数:

func mymin(x y)
  cond
    x>y then return y; end;
  end;
  return x;
end;

如果条件语句为真,则返回-1(否则为0)。因此,我将0复制到目标寄存器(此处为#%s rax)。如果左操作数更大,我将-1复制到%rax(使用条件移动)。 -1与条件(cmp $-1, %rax)的结果之间的比较确保了跳转,如果它是真的(-1 - -1 = 0)。

但恰恰相反。所以

mymin(2,3) = 3
mymin(1,0) = 1
// ...

出了什么问题?!

    .text

    .globl mymin
    .type mymin, @function
mymin:
    movq %rsi, %rax
    # calculate greater one between %rdi and %rsi to %rax (reg & reg)
    movq $0, %rax
    movq $-1, %r10
    cmpq %rdi, %rsi
    cmovgq %r10, %rax
    cmp $-1, %rax
    jz cond_1
    jmp cond_2
cond_1:
    movq %rsi, %rax
    ret
    jmp cond_2
cond_2:
    movq %rdi, %rax
    ret

1 个答案:

答案 0 :(得分:2)

根据我的评论(和@Jester的更正),如果您发现相反的值被存储,您可能在cmpq操作中混淆了“左”和“右”。

但是..这是另一个较短的内容:为什么要使用中间标志?

.text

.globl mymin
.type mymin, @function

mymin:
    movq %rsi, %rax
    # calculate greater one between %rdi and %rsi to %rax (reg & reg)
    movq %rdi, %rax
    cmpq %rsi, %rdi
    cmovle %rsi, %rax
    ret

rax加载了第一个值rsi,并假设这是较小的值。然后,您将rdirsi进行比较。如果此值较小或相等,请将rdi改为rax

免责声明:我不喜欢AT& T的奇怪语法,所以很可能,不,甚至可能,我犯了与你相同的错误。未经测试。 )