如何在 C++ 中使用内联汇编将两个大小矩阵相乘

问题描述 投票:0回答:1

我用 C++ 编写了这段代码,并使用内联汇编 _asm 进行方阵乘法。

#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
        lea esi, A
        lea edi, B
        lea edx, C
        outer_loop :
            push ecx
            mov ecx, n
            inner_loop :
                push ecx
                mov eax, [esi] ; load A[i][k]
                mov ebx, [edi] ; load B[k][j]
                imul eax, ebx ; compute A[i][k] * B[k][j]
                add [edx], eax ; accumulate result in C[i][j]
                add esi, 4 ; increment A pointer
                add edi, 4 ; increment B pointer
                add edx, 4 ; increment C pointer
                pop ecx
                loop inner_loop ; repeat for all k
            add esi, 400 ; jump to next row of A
            sub esi, ecx ; adjust A pointer
            mov eax, ecx
            imul eax, 4
            sub eax, n
            imul eax, 4
            lea edi, [edi + eax] ; jump to next column of B
            pop ecx
            loop outer_loop ; repeat for all 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;
}

它没有给出任何错误,但得到的矩阵 C 不正确。它给了我这些元素

5 12
0 0

我尝试更改偏移量,但没有帮助。

c++ visual-c++ x86 matrix-multiplication inline-assembly
1个回答
0
投票

这是基于您的代码的简单变体:

#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
            lea esi, A
            lea edi, B
            lea edx, C

idx_loop :  push ecx
            push edi
            push edx
            mov ecx, n

kdx_loop :  push ecx
            push edi
            push edx
            mov ecx, n

jdx_loop :  mov eax, [esi]; load A[i][k]
            mov ebx, [edi]; load B[k][j]
            imul eax, ebx; compute A[i][k] * B[k][j]
            add[edx], eax; accumulate result in C[i][j]
            add edi, 4; increment B pointer
            add edx, 4; increment C pointer
            loop jdx_loop; repeat for all j

            add esi, 4; increment A pointer
            pop edx
            pop edi
            add edi, 8; increment B pointer to the next row
            pop ecx
            loop kdx_loop; repeat for all k

            pop edx
            add edx, 8; increment C pointer to the next row
            pop edi
            pop ecx
            loop idx_loop; repeat for all 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;
}

这就是矩阵乘法通常的样子:

for(int i = 0; i < n; ++i) {        
   for(int k = 0; k < n; ++k) {      
      for(int j = 0; j < n; ++j)     {                
         C[i][j] += A[i][k] * B[k][j];            
      } 
   }    
}

另请查看this以了解为什么循环顺序会交换。

© www.soinside.com 2019 - 2024. All rights reserved.