You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

我的emu8086矩阵乘法代码为何无法输出预期结果?

EMU8086矩阵乘法与标量乘法代码错误排查与修正

核心错误分析

1. 矩阵乘法索引逻辑混乱

  • 原代码中mov bx, b[si]将B矩阵的元素值存入bx,后续却用c[bx]作为结果矩阵C的索引,这会导致索引完全错误(bx存储的是数值而非偏移量)。
  • 矩阵乘法的行列遍历逻辑错误:3x3矩阵乘法中,每个结果元素c[row][col]需要计算A的第row行与B的第col列对应元素的乘积和。原代码的di、si移动未实现行列的正确对应,且外层循环用错误的变量判断终止条件。

2. 数值转ASCII方式错误

  • 原代码直接给结果加48转换为ASCII,仅适用于0-9的个位数,但矩阵乘法结果(如30、60等)是多位数,直接转换会输出乱码或符号,必须实现多位数打印逻辑。

3. 标量乘法指令使用错误

  • 原代码的multiply_scalar_loop循环内,第一次执行mul c[di]后ax的值变为乘积,后续循环会用这个乘积继续乘下一个元素,而非原始的scalar值,每次循环前需重新加载scalar到ax。

修正后的代码

.model small
.stack 100h

.data
    a dw 1, 2, 3, 4, 5, 6, 7, 8, 9   ; 3x3矩阵A
    b dw 9, 8, 7, 6, 5, 4, 3, 2, 1   ; 3x3矩阵B
    c dw 9 dup(0)                    ; 结果矩阵C
    scalar dw 2
    newline db 13, 10, '$'           ; 换行符

.code
    mov ax, @data
    mov ds, ax

    ; 矩阵乘法: C = A * B
    mov cx, 3               ; 外层循环: A的行数(3行)
    mov di, 0               ; A的行索引偏移(每次+6,一行3个元素,每个占2字节)
matrix_row_loop:
    push cx                 ; 保存外层循环计数器
    mov cx, 3               ; 中层循环: B的列数(3列)
    mov si, 0               ; B的列索引偏移(每次+2,一列3个元素,每个占2字节)
matrix_col_loop:
    push cx                 ; 保存中层循环计数器
    mov cx, 3               ; 内层循环: 行列元素的乘积次数(3次)
    mov bx, 0               ; 临时存储当前元素的乘积和
    mov bp, di              ; 临时保存A的当前行起始偏移
    mov dx, si              ; 临时保存B的当前列起始偏移
inner_mul_loop:
    mov ax, a[bp]
    mul b[dx]
    add bx, ax              ; 累加乘积和
    add bp, 2               ; 移动到A的下一个元素(同列)
    add dx, 6               ; 移动到B的下一个元素(同行,下一行的同列)
    loop inner_mul_loop

    ; 将结果存入C的对应位置: C[row][col] = bx
    mov ax, di              ; 计算C的行偏移
    shr ax, 1               ; 转为元素索引(每个元素2字节)
    mov dx, si              ; 计算C的列偏移
    shr dx, 1
    mov cx, 3
    mul cx                  ; row * 3
    add ax, dx              ; row*3 + col = 线性索引
    shl ax, 1               ; 转为字节偏移
    mov c[ax], bx

    pop cx                  ; 恢复中层循环计数器
    add si, 2               ; 移动到B的下一列
    loop matrix_col_loop

    pop cx                  ; 恢复外层循环计数器
    add di, 6               ; 移动到A的下一行
    loop matrix_row_loop

    ; 打印矩阵乘法结果
    mov ah, 09h
    lea dx, newline
    int 21h
    call print_matrix

    ; 标量乘法: C = C * scalar
    mov cx, 9
    mov di, 0
scalar_mul_loop:
    mov ax, c[di]
    mul scalar
    mov c[di], ax
    add di, 2
    loop scalar_mul_loop

    ; 打印标量乘法结果
    mov ah, 09h
    lea dx, newline
    int 21h
    call print_matrix

    ; 退出程序
    mov ax, 4C00h
    int 21h

; 打印3x3矩阵的子程序
print_matrix proc
    mov cx, 3               ; 行数
    mov di, 0
print_row:
    push cx
    mov cx, 3               ; 列数
print_col:
    mov ax, c[di]
    call print_number       ; 打印当前数字
    mov ah, 02h
    mov dl, ' '             ; 元素间加空格
    int 21h
    add di, 2
    loop print_col
    pop cx
    mov ah, 09h
    lea dx, newline
    int 21h
    loop print_row
    ret
print_matrix endp

; 打印16位无符号数的子程序
print_number proc
    push bx
    push cx
    push dx
    mov cx, 0               ; 计数数字的位数
    mov bx, 10
number_divide:
    xor dx, dx
    div bx                  ; ax = ax / 10, dx = ax % 10
    push dx                 ; 保存余数
    inc cx
    cmp ax, 0
    jne number_divide
number_print:
    pop dx
    add dl, 48              ; 转为ASCII
    mov ah, 02h
    int 21h
    loop number_print
    pop dx
    pop cx
    pop bx
    ret
print_number endp
end

修正说明

  • 矩阵乘法:重新设计三层循环,分别遍历A的行、B的列及对应元素,正确计算乘积和并存入C的对应位置。
  • 打印模块:新增print_number子程序处理多位数ASCII转换,print_matrix子程序按3x3格式打印矩阵,提升可读性。
  • 标量乘法:每次循环重新加载当前矩阵元素到ax,与scalar相乘,确保计算逻辑正确。

内容的提问来源于stack exchange,提问作者Tamara Spasojevic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 09:34:53