Search code examples
assemblyx86asciinasm

Comparing numbers as strings of ASCII chars not working correctly in NASM


I am new to assembly language. I am using nasm under Ubuntu-Linux.
I found following example in a book. However, it is not working correctly.

section .text
    global main
main:
    mov ecx, [num1]
    cmp ecx, [num2]
    jg check_third_num
    mov ecx, [num2]
check_third_num:
    cmp ecx, [num3]
    jg _exit
    mov ecx, [num3]
_exit:
    mov [largest], ecx
    mov ecx, msg
    mov edx, len
    mov ebx, 1
    mov eax, 4
    int 0x80
    mov ecx, largest
    mov edx, 2
    mov ebx, 1
    mov eax, 4
    int 0x80
    mov eax, 1
    int 80h
 section .data
    msg db "The largest digit is:", 0xA, 0xD
    len equ $- msg
    num1 dd '17'
    num2 dd '52'
    num3 dd '31'
 segment .bss
    largest rest 2

It should find the largest digit. But the result is

The largest digit is:
17

Solution

  • The code only works for single digit numbers. I assume the original code in the book used such numbers, but you have changed it.

    The issue is that the numbers are stored as strings in this example, to avoid the need for a binary-to-text conversion. It works for single digits because the ascii codes for the digits are consecutive and have the same ordering as the numeric values. Thus if you write for example dd '2' that will allocate 4 bytes of storage, with the 4 bytes being: 0x32 0x00 0x00 0x00 (0x32 is the ascii code for 2). The code then uses these bytes as a 32 bit binary number, so the processor will interpret it to be 0x00000032 because x86 is a little endian architecture. I hope you see how this will work for all single digits.

    For multiple digits (up to 4) the endianness will make the cpu consider the digits from right to left, that is the numbers in your example will be interpreted as 71, 25 and 13, respectively(*). Since 71 is the largest of those the program will print the entry for that number, which is the string 17.


    *Actually the numbers will be 0x00003731, 0x00003235 and 0x00003133.