我必须对某种编译器进行编码,它的工作方式非常好,但是我的语义是" 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
答案 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
,并假设这是较小的值。然后,您将rdi
与rsi
进行比较。如果此值较小或相等,请将rdi
改为rax
。
(免责声明:我不喜欢AT& T的奇怪语法,所以很可能,不,甚至可能,我犯了与你相同的错误。未经测试。 )