Search code examples
assemblyx86nasm

NASM | unable to use 3 digit integer from stdin in mathematic operation / at all


I am currently working on a project in an introduction to assembly course in which we are asked to subtract a single digit integer from a three digit integer and display a two digit output. (implying the 3 digit integer is > 100 yet < 108)

I seem to be having issues dealing with this variable at every step. I wrote the below program to see if I could put it into the ax 16 bit register and move it back and can't seem to do even that.

I understand there may be an issue with the ascii value of it being larger than 1 byte, although seeing as 'ax' is a 2 byte register it doesn't seem like it would be problematic.

I am using the online rextester.com nasm compiler.

section .bss
    input: resb 1
    
section .text
    global _start
    
_start:
    
    mov eax,3
    mov ebx,0
    mov ecx,input
    mov edx,3
    int 80h
    
    mov [input],ax
    mov ax,[input]
    
    mov eax,4
    mov ebx,1
    mov ecx,input
    mov edx,1
    int 80h

    mov eax,1
    mov ebx,0
    int 80h

the output of this is garbage but without the mov I get the first digit of the int.


Solution

    1. You are reading 3 bytes into the buffer input which only has space for 1 byte (you wrote resb 1).

    2. If you type 572 as input to this program, the contents of the input buffer will be the three bytes corresponding to the characters 5, 7 and 2, whose ASCII character codes are 53, 55, 50 respectively. It is up to you to write the code to do the math that converts this into the integer 572 for use with arithmetic operations. In a higher-level language this would be done for you by a library function like scanf or atoi, but this is assembly and you have to do everything yourself. See NASM Assembly convert input to integer? for some examples.

    3. mov [input],ax would overwrite the input buffer with the contents of ax, which is the return value from the read system call (i.e. the number of bytes read, likely 3). That's not what you want to do. mov ax, [input] by itself is closer as it actually loads the 16-bit value from input into ax, but as noted, it won't be the desired value because you haven't done the decimal to binary conversion.