Author Topic: Finding the smallest number from four variables  (Read 212 times)

Offline Azrael998

  • Jr. Member
  • *
  • Posts: 12
Finding the smallest number from four variables
« on: November 09, 2020, 04:33:09 AM »
Hello, everyone so I have this program that finds the smallest number then stores it in a register. My question is how do I make the program better?, how do I improve the code?.

MASM code:
section   .text
   global _start         ;must be declared for using gcc

_start:                    ;tell linker entry point
   mov   ecx, [num1]       ;compare num1 and num2
   cmp   ecx, [num2]
   jg    compare_num3_and_num4
   mov   ecx, [num2]   

compare_num3_and_num4:
   mov   edx, [num3]
   cmp   edx, [num4]
   jg    _exit
   mov   ecx, [num3]

_exit:
   mov   [smallest], ecx
   mov   ecx,msg
   mov   edx, len
   mov   ebx,1   ;file descriptor (stdout)
   mov   eax,4   ;system call number (sys_write)
   int   0x80   ;call kernel

   mov   ecx,smallest
   mov   edx, 2
   mov   ebx,1   ;file descriptor (stdout)
   mov   eax,4   ;system call number (sys_write)
   int   0x80   ;call kernel

   mov   eax, 1
   int   80h

section   .data
   msg db "The smallest digit is: ", 0xA,0xD
   len equ $- msg
   num1 dd '53'
   num2 dd '42'
   num3 dd '9'
   num4 dd '21'

segment .bss
   smallest resb 2 
« Last Edit: November 09, 2020, 06:32:29 AM by Azrael998 »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2461
  • Country: us
Re: Finding the smallest number from four variables
« Reply #1 on: November 10, 2020, 02:36:54 AM »
Hi  Azrael998.
Code: [Select]
section   .text
   global _start         ;must be declared for using gcc

_start:                    ;tell linker entry point
   mov   ecx, [num1]       ;compare num1 and num2
   cmp   ecx, [num2]
   jg    compare_num3_and_num4
   mov   ecx, [num2]   

compare_num3_and_num4:
   mov   edx, [num3]
   cmp   edx, [num4]
   jg    _exit
   mov   ecx, [num3]

_exit:
   mov   [smallest], ecx
   mov   ecx,msg
   mov   edx, len
   mov   ebx,1   ;file descriptor (stdout)
   mov   eax,4   ;system call number (sys_write)
   int   0x80   ;call kernel

   mov   ecx,smallest
   mov   edx, 2
   mov   ebx,1   ;file descriptor (stdout)
   mov   eax,4   ;system call number (sys_write)
   int   0x80   ;call kernel

   mov   eax, 1
   int   80h

section   .data
   msg db "The smallest digit is: ", 0xA,0xD
   len equ $- msg
   num1 dd '53'
   num2 dd '42'
   num3 dd '9'
   num4 dd '21'

segment .bss
   smallest resb 2

The  biggest issue I see is that you haven't got numbers there, you've got text strings. Comparing text strings may give the result you want, but it isn't what you say you're doing. Remove the quote marks to make 'em numbers.

Then... you compare the first two strings and then switch to edx and compare the last two. You never do find the smallest of all four. In this case, it works out right, but if you change the order it won't. I'd stick with ecx.

At the end you've got "resb 2". This gives you only 2 bytes and you're putting a 4 byte register into it. Since it's the last variable in the program, you don't see the error. but if there were another it would be clobbered by the overflow. This just isn't right! "resb 4" or "resd 1" would fix it. They do the same thing, 4 bytes, 1 doubleword  is what you need.

More subtly, "jg" and "jl" work with signed numbers. "ja" and "jb" work with unsigned numbers. If you want to allow negative numbers, you need "jg". If you want to limit your program to positive numbers you might be better off with "ja".

Linux usually doesn't use carriage returns (0xD) but it probably doesn't hurt.

I don't know how you hope to improve your code, so I don't know if any of that helps.

Best,
Frank