2

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?

1 Answers1

2

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.

This is what is happening in the code

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.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • Hi, thanks so much for the help, I updated my code and I now have some new issues :( would you mind taking a look at it? – David Pupaza Jan 16 '22 at 13:45
  • 3
    @DavidPupaza Please do not modify the question after it is answered. That causes the answer not to match the question any more, which will confuse people who come here looking for answers to the same question. (Also, please don't delete your [questions](https://stackoverflow.com/q/70731842/) when you figure out the answer. Post an answer to your own question and accept it.) – Raymond Chen Jan 17 '22 at 01:41
  • I understand, sorry about that. – David Pupaza Jan 17 '22 at 16:24