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.
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.