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

使用MSVC内联汇编实现C++整数方阵乘法的问题排查

修复MSVC内联汇编实现整数方阵乘法的错误

你的汇编代码核心问题是循环逻辑和指针偏移完全不符合矩阵乘法的计算规则,矩阵乘法要求C[i][j] = Σ(A[i][k] * B[k][j])(k从0到n-1),但原代码的指针移动逻辑混乱,导致只计算了部分元素,最终结果错误。

核心错误点

  1. 内层循环逻辑错误:原代码每次内层循环同时移动A、B、C的指针,相当于计算A[i][k] * B[k][k]并累加到C[i][k],完全没按列访问B矩阵的元素。
  2. 指针偏移乱写:add esi, 400这种固定偏移毫无依据,矩阵行偏移应该是n * 4(每个int占4字节,一行n个元素)。
  3. C矩阵指针重复移动:内层循环每次移动edx,导致后续累加的不是同一个C[i][j]元素。
  4. B矩阵列访问逻辑错误:原代码对edi的调整公式完全错误,无法正确定位B矩阵的列元素。

修正后的完整代码

#include <iostream>
using namespace std;

int main() {
    int n = 2;
    int A[2][2] = { {1, 2}, {3, 4} };
    int B[2][2] = { {5, 6}, {7, 8} };
    int C[2][2] = { {0, 0}, {0, 0} };
    _asm {
        mov ecx, n               ; 外层循环:遍历A的行(i),循环n次
        lea esi, A               ; esi 指向A当前行的起始地址(A[i][0])
        lea edx, C               ; edx 指向C当前元素的起始地址(C[i][0])
        outer_loop_i:
            push ecx             ; 保存外层循环剩余次数
            mov ecx, n           ; 中层循环:遍历B的列(j),循环n次
            mov edi, edx         ; edi 指向当前要计算的C[i][j]
            mov ebx, esi         ; ebx 固定指向A[i][0],内层循环仅移动k的偏移
            inner_loop_j:
                push ecx         ; 保存中层循环剩余次数
                push edi         ; 保存C[i][j]的地址,后续写入结果用
                mov ecx, n       ; 内层循环:遍历k,计算累加和,循环n次
                xor eax, eax     ; eax 作为累加器,初始化为0
                mov edx, ebx     ; edx 指向A[i][k],初始为A[i][0]
                ; 计算B[0][j]的起始地址:B基地址 + j*4(j = n - 中层循环剩余次数)
                mov esi, B
                mov ecx, n
                sub ecx, [esp+8] ; 通过中层循环剩余次数计算j的索引
                imul ecx, 4
                add esi, ecx     ; esi 现在指向B[0][j]
                mov ecx, n       ; 恢复内层循环的次数
                inner_loop_k:
                    mov ecx, [edx]   ; 取出A[i][k]
                    mov edi, [esi]   ; 取出B[k][j]
                    imul ecx, edi    ; 计算乘积
                    add eax, ecx     ; 累加到结果
                    add edx, 4       ; 移动到A[i][k+1]
                    add esi, n*4     ; 移动到B[k+1][j](每行n个int,偏移n*4字节)
                    loop inner_loop_k
                ; 将累加结果写入C[i][j]
                pop edi
                mov [edi], eax
                add edi, 4           ; 移动到下一个C元素C[i][j+1]
                mov edx, edi
                pop ecx             ; 恢复中层循环计数器
                loop inner_loop_j
            add ebx, n*4         ; 移动到A的下一行A[i+1][0]
            mov esi, ebx
            pop ecx             ; 恢复外层循环计数器
            loop outer_loop_i
    }
    cout << "Resultant matrix:" << endl;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cout << C[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

关键修正说明

  • 三层循环结构:外层遍历行(i)、中层遍历列(j)、内层遍历k做累加,完全匹配矩阵乘法的计算逻辑。
  • 指针管理:
    • A矩阵固定当前行起始地址,内层循环仅按k偏移(+4字节)。
    • B矩阵先定位当前列的起始地址,内层循环按行偏移(+n*4字节)访问同一列的下一行元素。
    • C矩阵逐个元素写入,每次计算完一个元素后移动到下一个。
  • 累加器优化:用寄存器eax存储累加结果,避免直接操作内存的错误。

运行修正后的代码会得到正确结果:

Resultant matrix:
19 22 
43 50 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:48:10