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