Reputation: 23
So i have to multiply 'a' by a number of 'b' times and I tried to do it like this. I also took some procedures from other questions I found.
.MODEL SMALL
.DATA
a db 3, 4 dup (0)
b db 3, 4 dup (0) ;With the buffer that this provides, this now will allow you to input from the keyboard two double-digit numbers.
.CODE
mov ax, @data ;INITIALIZE DATA SEGMENT.
mov ds, ax
START:
;a
mov ah, 0ah
mov dx, offset a
int 21h
call string2number1 ;convert a to number (a->bx)
mov dx,bx ;(a->ax)
;b
mov ah, 0ah
mov dx, offset b
int 21h
call string2number2 ;convert b to number (b->bx)
;multiplication
mov cx,bx ;b->cx (multiply by cx(b) times)
mov bx,dx ;a->bx (to do a*a)
power:
mul bx
loop power
;dx:ax should now contain m^n (i hope)
;displaying dx:ax
mov bx,10 ;CONST
push bx ;Sentinel
.a: mov cx,ax ;Temporarily store LowDividend in CX
mov ax,dx ;First divide the HighDividend
xor dx,dx ;Setup for division DX:AX / BX
div bx ; -> AX is HighQuotient, Remainder is re-used
xchg ax,cx ;Temporarily move it to CX restoring LowDividend
div bx ; -> AX is LowQuotient, Remainder DX=[0,9]
push dx ;(1) Save remainder for now
mov dx,cx ;Build true 32-bit quotient in DX:AX
or cx,ax ;Is the true 32-bit quotient zero?
jnz .a ;No, use as next dividend
pop dx ;(1a) First pop (Is digit for sure)
.b: add dl,"0" ;Turn into character [0,9] -> ["0","9"]
mov ah,02h ;DOS.DisplayCharacter
int 21h ; -> AL
pop dx ;(1b) All remaining pops
cmp dx,bx ;Was it the sentinel?
jb .b ;Not yet
;-----------------------------------------
jmp skipProcedures
;CONVERT a TO NUMBER IN BX.
proc string2number1
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
mov si, offset a + 1
mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.
mov ch, 0 ;CLEAR CH, NOW CX==CL.
add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
mov bx, 0
mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mov ah, 0 ;CLEAR AH, NOW AX==AL.
mul bp ;AX*BP = DX:AX.
add bx,ax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov ax, bp
mov bp, 10
mul bp ;AX*10 = DX:AX.
mov bp, ax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.
ret
endp
;CONVERT b TO NUMBER IN BX.
proc string2number2
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
mov si, offset b + 1
mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.
mov ch, 0 ;CLEAR CH, NOW CX==CL.
add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
mov bx, 0
mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat2:
;CONVERT CHARACTER.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mov ah, 0 ;CLEAR AH, NOW AX==AL.
mul bp ;AX*BP = DX:AX.
add bx,ax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov ax, bp
mov bp, 10
mul bp ;AX*10 = DX:AX.
mov bp, ax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat2 ;COUNTER CX-1, IF NOT ZERO, REPEAT.
ret
endp
skipProcedures:
;---------------------------------------
mov ax,4c00h
int 21h
end start
The program wont let me press enter after I write the input for 'a'. Maybe I was wrong when I made the multiplication loop or when I tried to display dx:ax, but what does that have to do with letting me write input for a? I tried to explain as much as possible in the comments. What should I do?
Upvotes: 2
Views: 855
Reputation: 39166
I keep getting the same error as 'Operand types do not match on lines 18 and 19
That's because TASM knows that the a and b variables are byte-sized given that they were defined using the DB
directive, but your instructions mov bx,a
and mov cx,b
are word-sized operations. So, a mis-match.
Your program is using the a and b 'variables' for user input via the DOS.BufferedInput function 0Ah. Read all about this function here.
What your definitions should look like is:
.DATA
a db 3, 4 dup (0)
b db 3, 4 dup (0)
With the buffer that this provides, this now will allow you to input from the keyboard two double-digit numbers.
To actually start calculating with these numbers, you need to convert the text characters (by which they were inputted) into a simple number in the range [0,99].
Next code accomplishes this for the two-digit a input:
mov bx, offset a
mov ah, [bx+2] ; The tens ["0","9"]
mov al, [bx+3] ; The ones ["0","9"]
sub ax, "00" ; Converting to [0,9] on both at the same time
aad ; Combining both: AX = (AH * 10) + AL
mov ax,0 ; Initial result, i.e. m^0 power: jcxz power_done mul bx loop power power_done:
No matter the value by which you multiply (BX
), this multiplication will always yield zero. That's because you initialized AX=0
. This does not correspond to the comment "Initial result, i.e. m^0". Remember that m^0 = 1
.
You are trying to display the result with a single character output function. That's never going to be enough! See this Q/A for the correct method.
Upvotes: 2