0

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.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Tristan
  • 7
  • 2
  • Please comment your code with what you think each instruction does. Also, add appropriate indentation so it is readable. It is very difficult to explain what is wrong with code if one doesn't know what it is supposed to do. Lastly, why are you doing this weird mix of 32 and 64 bit code? – fuz Apr 07 '22 at 21:31
  • 1
    You should definitely not be getting `97` since that is not even in the array. I think you are running a different version of the code than what you posted. You should be getting `75` (and I do on my machine) because you are finding the largest signed value (222 is treated as -34). – Jester Apr 07 '22 at 22:22

1 Answers1

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
dVNE
  • 161
  • 9
  • `movb $0, %rdi` doesn't work, it won't assemble. The code in the question also can't exit with exit status `97` since that's not in the array, so it's not a [mcve] of what they actually ran. – Peter Cordes May 06 '22 at 10:41
  • @PeterCordes. Even if the question is a bit messed up, it's clear what he wanted to do – dVNE May 07 '22 at 17:05
  • Indeed, I was mostly replying to your "P.S. I still wonder how movb $0, %rdi might work..." which I figured was a rhetorical question, but just in case any future readers weren't sure and actually were wondering. But yes, the question does seem to be answerable despite lack of an actual MCVE consistent with the text. Enough of an attempt to satisfy the [How do I ask and answer homework questions?](https://meta.stackoverflow.com/q/334822) guidelines, even. – Peter Cordes May 07 '22 at 17:39
  • (Could still have been closed as a duplicate of [Difference between JA and JG in assembly](https://stackoverflow.com/q/20906639) or [Assembly - JG/JNLE/JL/JNGE after CMP](https://stackoverflow.com/q/9617877) but there's enough of a specific question here that answering wasn't actively bad. Probably low future value, but at least it got you some rep, and SO makes it a bit of a rep grind for newer users that know what they're talking about and are willing to pitch in and contribute. Welcome aboard, BTW :) – Peter Cordes May 07 '22 at 17:43