汇编程序签名比较

Assembler signed comparison

(使用AT&T语法的X86指令集。)

我目前正在开发一个程序来查找 long 值列表中的最小数字。

赋值如下

data_items: .long 13,-5,-8,4,-120

我遇到的问题是比较值,因为它们可能是负数。我正在将我的 data_items 视为有符号值,在 Whosebug 上的一些答案中使用 jg - 如果建议更大则跳转。但它对我不起作用,或者我可能用错了。

我写了一点"test"

movl $-7, %ebx    #write -7 to register ebx
movl , %ecx     #write 2 to register ecx

cmpl %ebx, %ecx   #compare -7 and 2
jl end_loop       #if -7 is less than 2, jump
movl , %ebx    # move 77 to register ebx

end_loop:

结果(在寄存器 %ebx 中)应该是 -7(或者实际上是 249,因为它的两个补码),但它是 77。

如何比较带符号的值?我是否必须确定它们是否已签名,记住这一点,如果它们已签名,则在比较之前否定它们?

它们已签名,因为您是这么说的,您永远无法测试是否已签名。任何位模式也是有效的无符号数。除了如何使用它们之外,没有什么可以区分它们。

在您的示例中,它将 ecxebx 进行比较,然后如果 ecx <s ebx 则转到 end_loop,但事实并非如此。

你的基本问题不是符号性(jl 对于有符号比较是正确的;如果你想要无符号你会使用 jb)但是 cmp 的操作数顺序说明。

这里有一些帮助记忆的方法:

cmp , %ecx 是合法指令,但 cmp %ecx, 不是。所以如果你把第二个操作数想成"the variable I'm testing",第一个操作数想成"the value I'm comparing it to",那么跳转指令的自然写法"Jump if the variable is less than the value"就对了

或者,如果你不喜欢那样,请记住 cmp 就像一个减法,它会丢弃结果并只存储标志,当你读取像 sub %ebx, %ecx 这样的指令时一个句子,使其在语法上正确的最简单方法是将逗号发音为 "from"。 "Subtract ebx from ecx" - 如果结果小于 0,jl 将跳转。

您阅读指令的方式,通过使用 jl 表示的 "less than",并将其插入到 cmp 指令中的逗号位置,导致错误回答。