Home > Software design >  Multiplying then dividing in nasm
Multiplying then dividing in nasm

Time:09-18

I'm just trying to learn about multiplying and dividing in nasm, and been experimenting with user input but it hasn't been working for me. I am just trying to multiply 2*3/2 so my input is 2 3 2 and it prints out an ascii blank character. I'm guessing its adding or subtracting '0' to change ascii to ints? Where do I put sub '0' or add '0' and why?

segment .data 
    
    segment .bss
    ;defining all variables
       num1 resb 2 ;num1 2 bytes
       num2 resb 2 ;nums2 2 bytes
       num3 resb 2 ;num2 2 bytes
    ;result
       res resb 1
    
    section .text
       global _start    ;must be declared for using gcc
        
    _start:             ;tell linker entry point
    
         
       ;reading num 1
       mov eax, 3 ;read
       mov ebx, 0  ;input
       mov ecx, num1 ;variable
       mov edx, 2 ;bytes
       int 0x80  ;end
    
    ;reading num 2
       mov eax, 3 ;read
       mov ebx, 0 ;input
       mov ecx, num2 ;variable
       mov edx, 2 ;bytes
       int 0x80   ;end
       
     ;reading num 3
       mov eax, 3 ;read
       mov ebx, 0  ;input
       mov ecx, num3 ;variable
       mov edx, 2 ;bytes
       int 0x80 ;end
       ; and subtracting ascii '0' to convert it into a decimal number
       
     
  
       ;moving variables in lower halfs
       mov ax, [num1]
       sub ax, '0'
       mov bx, [num2]
       sub bx, '0'
       ; multiply al and bl
       mul bx
       sub ax, '0'
       mov cx, [num3]
       sub cx, '0'
     ;dividing ax/cx
       div cx
       add ax, '0'
       mov [res], ax
    

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

mov ecx,res
mov edx, 1
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
     
  
    
    exit:    
       mov eax, 1
       int 0x80

but my output is always � or just nothing. Am I just adding '0' or subtracting '0' from the numbers wrong?

CodePudding user response:

I am just trying to multiply 2*3/2 so my input is 2 3 2

Because you're using these small single digit numbers, calculation can remain extremely simple.

However you seem to have a problem respecting the dimensions of things. I already told you this in my answer to your previous question. Single digit numbers are to be stored in byte-sized registers, and a byte-sized result must be written to the byte-sized res variable with a byte-sized operation.

mov al, [num1]
sub al, '0'    ; Converting from character to number
mov bl, [num2]
sub bl, '0'    ; Converting from character to number

When you say "multiply al and bl", then why do you execute mul bx which multiplies AX with BX ?

mul bl         ; Product is in AX

At this point, you still need to do the division on the numbers, so you shouln't yet make any conversion with that sub ax, '0'.

mov cl, [num3]
sub cl, '0'    ; Converting from character to number

Again "dividing ax/cx" would require clearing DX, but more importantly, you actually need the byte-sized division here:

div cl         ; Divides AX by CL, producing quotient in AL
add al, '0'    ; Converting from number to character
mov [res], al  ; Storing the single character, so use byte-sized operation

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

These lines are redundant and could explain seeing � displayed because ECX and EDX are not setup at this point.


To convert from character to number, you subtract 48.
To convert from number to character, you add 48.

The ASCII code of "0" is 48, so subtracting 48 produces the number 0
The ASCII code of "1" is 49, so subtracting 48 produces the number 1
The ASCII code of "2" is 50, so subtracting 48 produces the number 2
...
The ASCII code of "9" is 57, so subtracting 48 produces the number 9

  • Related