0
.model small
.stack 100h

.data
    a dw 1, 2, 3, 4, 5, 6, 7, 8, 9
    b dw 9, 8, 7, 6, 5, 4, 3, 2, 1
    c dw 0, 0, 0, 0, 0, 0, 0, 0, 0
    scalar dw 2

.code
    mov ax, @data
    mov ds, ax

    ; Matrix multiplication
    mov cx, 3 ; outer loop counter (rows of a)
    mov di, 0 ; index for a
    mov si, 0 ; index for b

multiply_loop:
    push cx ; save outer loop counter

    mov bx, 0 ; index for c
    mov dx, 0 ; inner loop counter

    inner_loop:
        mov ax, a[di]
        mov bx, b[si]
        mul bx
        add c[bx], ax

        add di, 2 ; move to next element in a
        add si, 2 ; move to next element in b
        inc dx ; increment inner loop counter
        cmp dx, 3 ; check if inner loop counter reached 3
        jl inner_loop ; if not, continue inner loop

    pop cx ; restore outer loop counter
    add di, 2 ; move to next row in a
    mov si, 0 ; reset index for b
    inc bx ; increment index for c
    cmp bx, 3 ; check if outer loop counter reached 3
    jl multiply_loop ; if not, continue outer loop

    ; Print the result of matrix multiplication
    mov ah, 2 ; print character function
    mov dl, 13 ; carriage return
    int 21h
    mov dl, 10 ; line feed
    int 21h

    mov cx, 9 ; total elements in c
    mov di, 0 ; index for c

print_loop:
    mov ax, c[di]
    add ax, 48 ; convert to ASCII
    mov dl, al ; move lower byte to dl
    mov ah, 2 ; print character function
    int 21h

    inc di ; move to next element in c
    loop print_loop ; continue printing until all elements are printed

    ; Multiply the result by the scalar
    mov cx, 9 ; total elements in c
    mov di, 0 ; index for c
    mov ax, scalar

multiply_scalar_loop:
    mul c[di]
    mov c[di], ax

    inc di ; move to next element in c
    loop multiply_scalar_loop ; continue multiplying until all elements are multiplied

    ; Print the result after scalar multiplication
    mov ah, 2 ; print character function
    mov dl, 13 ; carriage return
    int 21h
    mov dl, 10 ; line feed
    int 21h

    mov cx, 9 ; total elements in c
    mov di, 0 ; index for c

print_scalar_loop:
    mov ax, c[di]
    add ax, 48 ; convert to ASCII
    mov dl, al ; move lower byte to dl
    mov ah, 2 ; print character function
    int 21h

    inc di ; move to next element in c
    loop print_scalar_loop ; continue printing until all elements are printed

    mov ax, 4C00h ; exit program
    int 21h
end

Can someone help me with this code, it's printing some symbols and zeros when I run it. Where is the error?

I tried to multiply 2 matrices and to multiply result matrix with scalar and it's not printing good.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76

2 Answers2

1
.data
    a dw 1, 2, 3, 4, 5, 6, 7, 8, 9
    b dw 9, 8, 7, 6, 5, 4, 3, 2, 1
    c dw 0, 0, 0, 0, 0, 0, 0, 0, 0
    scalar dw 2

All of your matrices are 2 dimensional (3 x 3); they're even square matrices. It will be much clearer if you wrote your definitions that way too:

.data
    a      dw 1, 2, 3
           dw 4, 5, 6
           dw 7, 8, 9
    b      dw 9, 8, 7
           dw 6, 5, 4
           dw 3, 2, 1
    c      dw 0, 0, 0
           dw 0, 0, 0
           dw 0, 0, 0
    scalar dw 2

Multiplying

mov bx, b[si]
mul bx
add c[bx], ax

If BX is supposed to contain an offset in the c array, why then do you destroy that value in loading from the b array (mov bx, b[si]) ?
If DX is supposed to contain your inner loop counter, why then do you allow it getting destroyed by the word-sized multiplication mul bx that leaves a product in the register combo DX:AX ?

inc bx           ; increment index for c
cmp bx, 3        ; check if outer loop counter reached 3
jl multiply_loop ; if not, continue outer loop

You need to make up your mind here! The outer loop counter is in CX; why then look at BX ? And the index for the c array would have to increment in steps of 2 since it is a word-sized array.

In all, your matrix multiplication doesn't do what it needs to do. You are on a learning path here, so please don't expect me to write it all for you, but in the past I have answered a similar question that you can study and that should help you find it mostly on your own.

Printing

In the print loop, you seem to expect that the elements in the c array will all be in the single-digit range. This will not be the case! You need a conversion code that can convert the value in AX into a string of characters. I have prepared such a code in Displaying numbers with DOS.

Multiplying again

  mov ax, scalar
multiply_scalar_loop:
  mul c[di]
  mov c[di], ax
  inc di                  ; move to next element in c
  loop multiply_scalar_loop

In this loop you need to reload the scalar on every iteration, not just the first time. And to actually "move to next element in c", you need to add 2 instead of 1.

Printing again

Exactly the same as above.

Good luck

Once you get this much better and it still doesn't work, then don't hesitate and post your improved code stating whatever problems remain.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
0

Code should be ok now :) Compiles in emu8086, in masm "jump destination too far by 7 bytes" :D I don't know any tricks how to deal with this, except maybe reduce code size, so I used trick of mine :D

enter image description here

.model small
.stack 100h

.data
    a dw 1, 2, 3
      dw 4, 5, 6
      dw 7, 8, 9
      
    b dw 9, 8, 7
      dw 6, 5, 4
      dw 3, 2, 1
      
    cc dw 0, 0, 0
      dw 0, 0, 0
      dw 0, 0, 0
      
    scalar dw 2 
    
    scalar_mtx dw 0, 0, 0
               dw 0, 0, 0
               dw 0, 0, 0   
               
    matrix  db 4 dup(32),124,19 dup(32),124,13,10,'$'
            db 4 dup(32),124,19 dup(32),124,13,10,'$'
            db "? = |",19 dup(32),124,13,10,'$'
            db 4 dup(32),124,19 dup(32),124,13,10,'$'
            db 4 dup(32),124,19 dup(32),124,13,10,'$'
               
.code
    start:
    mov ax, @data
    mov ds, ax

    mov ax,0003h
    int 10h

    ; Matrix multiplication
    mov cx, 9 ; outer loop counter,we have to calculate 9 values in C 
    mov bx, 0 ; index for A
    mov si, 0 ; index for B
    mov di, 0 ; index for C
    
    multiply_loop:
       push cx ; save outer loop counter
       mov cx,3    ; row A x each column B

       inner_loop:
          mov ax, a[bx] ; get element A        
        
          mul word ptr b[si] ; mul element B
        
          add cc[di], ax   ; save result in C              
               
          add bx, 2 ; move to next element in row A
          add si, 6 ; move to next element in column B

        loop inner_loop 

        cmp si,22   ; we multiplied row in A by all columns in B
                    ; so move to next row in A
        jz next_row_in_A

        sub bx,6    ;back to first element of the row in A
        sub si,16   ;move to next colums in B
    
        jmp calculate_next_value_in_C         
    
        next_row_in_A:   
           mov si, 0 ; reset to first element in B          
     
        calculate_next_value_in_C:    
           add di,2 ; increment index in C
           pop cx ; restore outer loop counter
        
    loop multiply_loop 

;;;;;;;;;;
;;; matrix scalar

    mov bx, offset cc  
    mov di, offset scalar_mtx
    mov cx, 9
    
    scalar_loop:    
        mov ax,[bx]
        mul [scalar]
        mov [di],ax
        add bx,2
        add di,2    
    loop scalar_loop  
     
;;;;;;;;;;;;;
;;;  print all

    ;print matrix A               
    mov bx, offset a  
    mov dx,0801h
    mov si,offset matrix  
    mov al,'A' 
    
    call ShowMatrix   

    ;print matrix B
    mov bx, offset b
    mov dx,0120h
    mov si,offset matrix  
    mov al,'B' 
    
    call ShowMatrix
    
    ;print matrix C
    mov bx, offset cc  
    mov dx,0820h
    mov si,offset matrix  
    mov al,'C' 
    
    call ShowMatrix
   
    ;print matrix SCALAR
    mov bx, offset scalar_mtx  
    mov dx,0f01h
    mov si,offset matrix  
    mov al,'S' 
    
    call ShowMatrix  
             
    mov ah,8
    int 21h

    mov ax, 4C00h ; exit program
    int 21h   

ShowMatrix proc     ;cutting edge graphics :D
    push bx
    push dx

   ; mov si,offset matrix
    add si,56      ;letter modification
    mov [si],al
    sub si,56 
    
    mov ah,2    ;move cursor to dh,dl
    mov bh,0
    int 10h 
    
    mov ah,9    ;row 1
    mov dx, si
    int 21h
     
    pop dx
    add dh,1 
    mov ah,2    ;move cursor to dh,dl
    mov bh,0
    int 10h 
    push dx
  
    add si,28   ;row 2
    mov ah,9
    mov dx, si
    int 21h   
    
    pop dx
    add dh,1 
    mov ah,2    ;move cursor to dh,dl
    mov bh,0
    int 10h 
    push dx
  
    add si,28   ;row 3
    mov ah,9
    mov dx, si
    int 21h 

    pop dx
    add dh,1 
    mov ah,2    ;move cursor to dh,dl
    mov bh,0
    int 10h 
    push dx
  
    add si,28   ;row 4
    mov ah,9
    mov dx, si
    int 21h 
    
    pop dx
    add dh,1 
    mov ah,2    ;move cursor to dh,dl
    mov bh,0
    int 10h 
    push dx
  
    add si,28   ;row 5
    mov ah,9
    mov dx, si
    int 21h 

    pop dx
    sub dh,4
    add dl,6 
    mov ah,2    ;move cursor to dh,dl
    mov bh,0
    int 10h 
    
    pop si
    
    call itoa
       
    ret      
ShowMatrix endp

itoa proc
    mov cx,9        ; number of elements in matrix    
    mov bx,10000    
    mov di,0        ;flag, print 0 or not
    
    AllElementsInMatrix:  
        push cx          
        mov cx,5    
        
        PositionInNumber: 
            push dx ; remember screen coords
            xor dx,dx        
            mov ax,[si]
            div bx                        
            cmp ax,0
            jnz PrintDigit                
            jz Zero
            
            PrintDigit: 
                
                mov di,1
                mov [si],dx               
                mov ah,2
                mov dl,al
                add dl,30h
                int 21h
                jmp BxDiv10
            
            Zero:
               
                cmp di,0
                jz no_zero
                jmp print_zero          
                          
                no_zero:          
                    cmp cx,1
                    jz value_is_zero
                        
                    mov ah,2
                    mov dl,' '
                    int 21h
                    jmp BxDiv10
                    
                    value_is_zero:                    
                        mov ah,2
                        mov dl,'0'
                        int 21h
                    
                        jmp BxDiv10     
                    
                print_zero:          
    
                    mov ah,2
                    mov dl,'0'
                    int 21h
               
             BxDiv10:
    
                xor dx,dx      
                mov ax,bx      
                mov bx,10 
                div bx    
                mov bx,ax
                pop dx    

         loop PositionInNumber
         
         pop cx          
         
         push cx
         push bx
         push dx
            
         xor dx,dx
         mov ax,cx
         mov bx,3
         div bx
            
         cmp dx,1
         jz move_to_new_row           
         jmp same_row
                              
         move_to_new_row:  
            pop dx   
            add dh,2
            mov ah,2    
            mov bh,0
            int 10h                                              
            push dx                  
                        
            jmp End1
                    
         same_row:  
            
            mov ah,2
            mov dl,' '                    
            int 21h                                                        
                   
         End1:
                jmp NastyTrick
             NastyTrickDone:
             
    loop AllElementsInMatrix 

    jmp end_proc

    NastyTrick:
      pop dx   
      pop bx
             
      mov bx,10000 
      mov di,0
      add si,2    
      pop cx            
      jmp NastyTrickDone
      
      end_proc:
    ret      
itoa endp

end start

Nassau
  • 377
  • 1
  • 1
  • 8
  • 1
    That is not how matrix multiplication works! See https://en.wikipedia.org/wiki/Matrix_multiplication#:~:text=In%20mathematics%2C%20particularly%20in%20linear,rows%20in%20the%20second%20matrix. – Sep Roland May 29 '23 at 20:36
  • @0Signal - if you are going to fix this code, why destroy BX inside the inner loop at all? You could `mul word ptr b[si]`, or load into DX which `mul` already destroys for its output. Loading into BX is inconvenient for no reason. Also, if you don't have enough regs and need to do an extra save/restore, do it in the outer loop, not for the *inner* loop counter. Use CX for the inner counter, or BP if you're only going to use push/pop, not `[bp - 2]` or something for the outer loop counter. I guess none of DI, SI, or BX are always 0..6, so you can't just `cmp` on them. – Peter Cordes May 29 '23 at 21:13
  • @SepRoland: Are you sure this isn't a correct matmul? It's sort of like a triple-nested loop collapsed down to double-nested with branching in the outer loop to adjust SI. The inner loop's iteration order, along contiguous rows of all 3 matrices, is one possible technique for SIMD matmuls, e.g. in the appendix in [‘What Every Programmer Should Know About Memory’](https://stackoverflow.com/a/47714514). Instead of doing all of one row x column dot product, you iterate along a row in the destination adding into its elements while looping over input rows. – Peter Cordes May 29 '23 at 21:17
  • 1
    @PeterCordes I'm pretty sure it is not correct. Just looking at the numbers from the debug window: first row of *a* times first **column** of *b* should produce 1 * 9 + 2 * 6 + 3 * 3 = 9 + 12 + 9 = 30 = 1Eh But the dump shows 2Eh which is what we get from multiplying the first row of *a* with the first **row** of *b*. – Sep Roland May 29 '23 at 21:27
  • @SepRoland: Ok, I didn't try to actually check the numbers. It looks like it might be trying to implement the a correct matmul algorithm, though. I thought from your comment that it was going to be just an element-wise product, but that's not the case, it should be doing enough total multiplies (9x3 = 27) for a 3x3 matrix product. That is how matmul works, although it's certainly possible it got a detail wrong. Or perhaps it's doing `b * a` instead of `a * b` or something. – Peter Cordes May 29 '23 at 21:41
  • I multiplied row A by row B instead of row A by column B. :/ I'll change that.. – Nassau May 30 '23 at 06:16
  • I changed code, I hope this is better solution. Thank You for instructions. :)) – Nassau May 30 '23 at 09:07