混淆比较负整数

Confusion with comparing negative integers

我已经开始学习汇编了,但我对示例程序有些困难。

我写了一个宏来找到数组中的最小值:

%macro min 3    
    mov ecx, dword[%2]
    mov r12, 0
    lea rbx, [%1]
    movsx eax, word[rbx+r12*4] ; inizializza il minimo con il primo elemento dell'array

%%minLoop:
    cmp eax, [rbx+r12*4]
    jl %%notNewMin
    movsx eax, word[rbx+r12*4]

    %%notNewMin:
        inc r12

    loop %%minLoop
    mov [%3], eax

%endmacro

section .data
EXIT_SUCCESS equ 0
SYS_exit     equ 60

list1 dd 4, 5, 2, -3, 1
len1 dd 5
min1 dd 0

section .text
global _start

_start:
    min list1, len1, min1
last:
    mov rax, SYS_exit ; exit
    mov rdi, EXIT_SUCCESS ; success
    syscall

这个程序成功编译,但是当我调试它(​​使用 DDD)时,在 eax 寄存器中我有十六进制值 0xFFFFFFFD 和十进制值 4294967293

但是,如果我使用计算器,0xFFFFFFFD 确实是 -3,这是正确的值。

你认为我的程序正确吗?

提前感谢您的回答。

这是不正确的,虽然用小值测试它会隐藏错误。

数组元素的类型处理不一致。它们被定义为dd,地址计算与之一致(使用4*index)。 cmp eax, [rbx+r12*4]也符合这一点。但是movsx eax, word[rbx+r12*4]不是,现在突然用不到元素的高16位

这可以很容易地通过写 mov eax, [rbx+r12*4] 来解决。

顺便说一下,您通常不应该使用 loop,它在大多数现代处理器上是 quite slow

0xFFFFFFFD 是 32 位值 1111_1111_1111_1111_1111_1111_1111_1101,这可能是最接近 CPU 物理内部的隐喻(32 个具有不同电流水平或磁极编码逻辑的单元格值 0 或 1).

无论您解释为-3还是4294967293或完全不同的东西(比如32个独立的true/false值)取决于代码,即使用值。

负整数通常使用二进制补码编码,您正在用 -3 值观察。

调试器不知道您是将值解释为有符号还是无符号(除非您通过格式化参数指定它),因此它会选择一种格式并像那样显示,在您的情况下为无符号 32 位值,这意味着您看到的是 4294967293 而不是 -3,但是这两个按位是相同的,而且对于像 add/sub/cmp/test/... 这样的算术指令,该值也是相同的,只是结果(和标志)的解释通过以下代码将决定值是 "signed" 还是 "unsigned".

符号本身不是编码信息的一部分,或者有时最高位被视为 "sign" 位,因为所有负值都设置了最高位,但这就是为什么有符号 8 位值的原因只能存储值 -128..+127,而无符号 8 位值可以存储值 0..+255(即两种解释恰好涵盖 256 个不同的值,因为 8 位可以产生 0/1 模式的 256 种不同组合,但是有符号解释 "starts" 在“0x80 = -128”,而无符号解释 "starts" 在“0x00 = 0”和 0x80 已经被解释为 +128。但是这两种解释都只使用 8 位值,没有其他附加信息,例如某种类型等。

例如

cmp    eax, ebx   ; check if eax is bigger than ebx
; now if the values were meant as unsigned, then use "ja" branch
ja     eax_is_bigger_as_unsigned
; but if you meant the values as signed, then you should use "jg" (testing different flags)
jg     eax_is_bigger_as_signed

因此 cmp 本身并不关心您如何解释该位模式,它会在 EFLAGS 寄存器中设置足够的标志,使两种情况下的条件分支成为可能。