英文:
Why does my emu8086 code for matrix multiplication not print the expected result?
问题
这段代码看起来是一个汇编程序,其目的是执行矩阵乘法并将结果与标量相乘,然后将结果打印出来。在你的描述中提到输出中包含符号和零,这可能是由于代码中的一些错误造成的。以下是可能导致问题的几个地方:
-
mul bx
指令:在执行乘法操作之前,你应该确保AX
寄存器中的值已被清零,因为mul
指令将AX
寄存器中的值与BX
相乘,并将结果存储在DX:AX
中。你可以在执行mul
之前插入xor dx, dx
来清零DX
寄存器。 -
存储乘法结果的方式:在代码的
add c[bx], ax
行中,你正在将乘法结果添加到一个地址中,而不是将其存储在c
数组中的正确位置。你应该使用mov
指令将乘法结果存储在c
数组中的正确位置,而不是add
。 -
打印结果:在打印结果之前,你应该确保将
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中编译,在masm中报错“跳转目标太远,超出7个字节” 我不知道如何解决这个问题,除了可能减小代码大小,所以我用了我的技巧
[![进入图像描述][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 "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][1]][1]
<pre>
.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
</pre>
[1]: https://i.stack.imgur.com/sH3Mx.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论