'Finding the minimum value on a list Assembly Language GAS
I'm trying to find the minimum value of a list using assembly language. I'm trying to use -1 to compare all the other values to. my current code is
data_items:
.byte 3,67,34,222,45,75,54,34,44,33,22,11,66,-1
.section .text
.global _start
_start:
movb $0, %rdi
movb data_items(,%rdi,1),%al
movb %al, %bl
start_loop:
cmpb $-1, %al
je loop_exit
inc %edi
movb data_items(,%rdi,1), %al
cmpb %bl, %al
jle start_loop
movb %al, %bl
jmp start_loop
loop_exit:
movb $1, %al
int $0x80
I keep getting 97 as the output and I'm pretty stuck. Can anyone tell me where I'm wrong? Assembly language is brutal.
Solution 1:[1]
Your code has two problems.
First, using jle start_loop
, you jump to start_loop when al <= bl.
But, since %al is the new number to check and %bl is the lowest number found up to now, what you should do is jg start_loop
, that is: jump when al > bl and thus we haven't found a number less than the minimum.
data_items:
.byte 3,67,34,222,45,75,54,34,44,33,22,11,66,-1
.section .text
.global _start
_start:
movb $0, %rdi
movb data_items(,%rdi,1),%al
movb %al, %bl
start_loop:
cmpb $-1, %al
je loop_exit
inc %edi
movb data_items(,%rdi,1), %al
cmpb %bl, %al
jg start_loop # if al > bl we have not found the new minimum and we can start again
movb %al, %bl
jmp start_loop
loop_exit:
movb $1, %al
int $0x80
But this code is still wrong.
Another problem is the sign of numbers.
If you want to consider data_items as an array of signed ints, 222 will be -34. If you consider data_items as unsigned ints, -1 will be 255. Thus what you could do is replacing jg start_loop
with ja start_loop
data_items:
.byte 3,67,34,222,45,75,54,34,44,33,22,11,66,-1
.section .text
.global _start
_start:
movb $0, %rdi
movb data_items(,%rdi,1),%al
movb %al, %bl
start_loop:
cmpb $-1, %al
je loop_exit
inc %edi
movb data_items(,%rdi,1), %al
cmpb %bl, %al
ja start_loop # if al > bl we have not found the new minimum and we can start again
movb %al, %bl
jmp start_loop
loop_exit:
movb $1, %al
int $0x80
On my machine, changing a bit your code, I get correctly 3 as exit code.
P.S. I still wonder how movb $0, %rdi
might work...
This is the version which I run on my x86_64 box (I assume you are on x86_64 since you used %rdi)
/* min.S */
/* Compile with gcc -nostdlib min.S */
#include <syscall.h>
data_items:
.byte 3,67,34,222,45,75,54,34,44,33,22,11,66,-1
.section .text
.global _start
_start:
movq $0, %rdi
leaq data_items(%rip),%rdi
movb (%rdi), %al
movb %al, %bl
start_loop:
cmpb $-1, %al
je loop_exit
inc %rdi
movb (%rdi), %al
cmpb %bl, %al
ja start_loop # if al > bl we have not found the new minimum and we can start again
movb %al, %bl
jmp start_loop
loop_exit:
movq $SYS_exit, %rax
movzx %bl, %rdi
syscall
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |