我的emu8086矩阵乘法代码为什么没有输出预期结果?

huangapple go评论56阅读模式
英文:

Why does my emu8086 code for matrix multiplication not print the expected result?

问题

这段代码看起来是一个汇编程序,其目的是执行矩阵乘法并将结果与标量相乘,然后将结果打印出来。在你的描述中提到输出中包含符号和零,这可能是由于代码中的一些错误造成的。以下是可能导致问题的几个地方:

  1. mul bx 指令:在执行乘法操作之前,你应该确保 AX 寄存器中的值已被清零,因为 mul 指令将 AX 寄存器中的值与 BX 相乘,并将结果存储在 DX:AX 中。你可以在执行 mul 之前插入 xor dx, dx 来清零 DX 寄存器。

  2. 存储乘法结果的方式:在代码的 add c[bx], ax 行中,你正在将乘法结果添加到一个地址中,而不是将其存储在 c 数组中的正确位置。你应该使用 mov 指令将乘法结果存储在 c 数组中的正确位置,而不是 add

  3. 打印结果:在打印结果之前,你应该确保将 AL 寄存器中的值转换为 ASCII 字符。你已经使用了 add ax, 48 来做到这一点,但在此之前,你需要将 AH 寄存器设置为 0,以确保只有 AL 寄存器中的值被转换为 ASCII 字符。

你可以在这些地方进行代码修正,以解决输出问题。如果还有其他问题,可以进一步调试代码。希望这能帮助你找到问题所在。

英文:
.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.

答案1

得分: 1

以下是您要翻译的代码部分:

.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
mov bx, b[si]
mul bx
add c[bx], ax
inc bx
cmp bx, 3
jl multiply_loop
mov ax, scalar
multiply_scalar_loop:
   mul c[di]
   mov c[di], ax
   inc di
   loop multiply_scalar_loop

希望这有助于您理解代码的建议和修改。如果您有其他问题,请随时提出。

英文:

> .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 https://stackoverflow.com/questions/45904075/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.

答案2

得分: 0

代码现在应该没问题了 我的emu8086矩阵乘法代码为什么没有输出预期结果? 在emu8086中编译,在masm中报错“跳转目标太远,超出7个字节” 我的emu8086矩阵乘法代码为什么没有输出预期结果? 我不知道如何解决这个问题,除了可能减小代码大小,所以我用了我的技巧 我的emu8086矩阵乘法代码为什么没有输出预期结果?

[![进入图像描述][1]][1]

.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 ; 外部循环计数器,我们必须计算C中的9个值
    mov bx, 0 ; A的索引
    mov si, 0 ; B的索引
    mov di, 0 ; C的索引
    
    multiply_loop:
        push cx ; 保存外部循环计数器
        mov cx,3    ; A的行 x 每个B的列

        inner_loop:
            mov ax, a[bx] ; 获取A的元素        
            mul word ptr b[si] ; 乘以B的元素        
            add cc[di], ax   ; 将结果保存在C中              

            add bx, 2 ; 移动到A中的下一个元素
            add si, 6 ; 移动到B中的下一个元素

        loop inner_loop 

        cmp si,22   ; 我们已经将A中的一行乘以了所有的B中的列
                    ; 所以移动到A中的下一行
        jz next_row_in_A

        sub bx,6    ; 回到A中行的第一个元素
        sub si,16   ; 移动到B中的下一列
    
        jmp calculate_next_value_in_C         
    
    next_row_in_A:   
        mov si, 0 ; 重置为B中的第一个元素          
     
    calculate_next_value_in_C:    
        add di,2 ; 增加C中的索引
        pop cx ; 恢复外部循环计数器
        
    loop multiply_loop 

;;;;;;;;;;;
;;; 矩阵标量

    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  
     
;;;;;;;;;;;;;
;;;  打印全部

    ; 打印矩阵A               
    mov bx, offset a  
    mov dx,0801h
    mov si,offset matrix  
    mov al,'A' 
    
    call ShowMatrix   

    ; 打印矩阵B
    mov bx, offset b
    mov dx,0120h
    mov si,offset matrix  
    mov al,'B' 
    
    call ShowMatrix
    
    ; 打印矩阵C
    mov bx, offset cc  
    mov dx,0820h
    mov si,offset matrix  
    mov al,'C' 
    
    call ShowMatrix
   
    ; 打印矩阵标量
    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 ; 退出程序
    int 21h   

ShowMatrix proc     ;前沿的图形 :D
    push bx
    push dx

    ; mov si,offset matrix
    add si,56      ;字母修改
    mov [si],al
    sub si,56 
    
    mov ah,2    ;将光标移动到dh,dl
    mov bh,0
    int 10h 
    
    mov ah,9    ;第1行
    mov dx, si
    int 21h
     
    pop dx
    add dh,1 
    mov ah,2    ;将光标移动到dh,dl
    mov bh,0
    int 10h 
    push dx
  
    add si,28   ;第2行
    mov ah,9
    mov dx, si
    int 21h   
  
    pop dx
    add dh,1 
    mov ah,2    ;将光标移动到dh,dl
    mov bh,0
    int 10h 
    push dx
  
    add si,28   ;第3行
    mov ah,9
    mov dx, si
    int 21h 

    pop dx
    add dh,1 
    mov ah,2    ;将光标移动到dh,dl
    mov bh,0
    int 10h 
    push dx
  
    add si,28   ;第4行
    mov ah,9
    mov dx, si
    int 21h 
    
    pop dx
    add dh,1 
    mov ah,2    ;将光标移动到dh,dl
    mov bh,0
    int 10h 
    push dx
  
    add si,28   ;第5行
    mov ah,9
    mov dx, si
    int 21h 

    pop dx
    sub dh,4
    add dl,6 
    mov ah,2    ;将光标移动到dh,dl
    mov bh,0
    int 10h 
    
    pop si
    
    call itoa

<details>
<summary>英文:</summary>

Code should be ok now :) Compiles in emu8086, in masm &quot;jump destination too far by 7 bytes&quot; :D I don&#39;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][1]][1]

&lt;pre&gt;
.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,&#39;$&#39;
            db 4 dup(32),124,19 dup(32),124,13,10,&#39;$&#39;
            db &quot;? = |&quot;,19 dup(32),124,13,10,&#39;$&#39;
            db 4 dup(32),124,19 dup(32),124,13,10,&#39;$&#39;
            db 4 dup(32),124,19 dup(32),124,13,10,&#39;$&#39;
               
.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,&#39;A&#39; 
    
    call ShowMatrix   

    ;print matrix B
    mov bx, offset b
    mov dx,0120h
    mov si,offset matrix  
    mov al,&#39;B&#39; 
    
    call ShowMatrix
    
    ;print matrix C
    mov bx, offset cc  
    mov dx,0820h
    mov si,offset matrix  
    mov al,&#39;C&#39; 
    
    call ShowMatrix
   
    ;print matrix SCALAR
    mov bx, offset scalar_mtx  
    mov dx,0f01h
    mov si,offset matrix  
    mov al,&#39;S&#39; 
    
    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,&#39; &#39;
                    int 21h
                    jmp BxDiv10
                    
                    value_is_zero:                    
                        mov ah,2
                        mov dl,&#39;0&#39;
                        int 21h
                    
                        jmp BxDiv10     
                    
                print_zero:          
    
                    mov ah,2
                    mov dl,&#39;0&#39;
                    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,&#39; &#39;                    
            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

&lt;/pre&gt;


  [1]: https://i.stack.imgur.com/sH3Mx.png

</details>



huangapple
  • 本文由 发表于 2023年5月28日 22:01:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76351867.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定