Search code examples
assemblyx86-64negative-numberyasm

Confusion with comparing negative integers


I've begun to study assembly and I have some difficult with a sample program.

I wrote a macro that would find the minimum in an array:

%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

This program successfully compile, but when I debug it (with DDD), in the eax register I have the hex value 0xFFFFFFFD and the decimal value of 4294967293.

But, if I use a calculator 0xFFFFFFFD is really -3 which is the correct value.

In your opinion, is my program correct?

Thanks in advance for your answers.


Solution

  • It's not correct, though testing it with small values would hide the bug.

    There is an inconsistency in what type of the elements of the array are treated as. They were defined with dd, and the address calculation is consistent with that (using 4*index). cmp eax, [rbx+r12*4] is also consistent with that. But movsx eax, word[rbx+r12*4] is not, now suddenly the upper 16 bits of the element are not used.

    This can be fixed very easily by writing mov eax, [rbx+r12*4] instead.

    By the way you should usually not use loop, it's quite slow on most modern processors.