assembly 函数转置矩阵中的指针问题

v9tzhpje  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(113)

在我的代码IM试图转置动态矩阵(IN64)使用汇编编写的函数似乎IM试图从矩阵外部读取或我犯了一个错误,而试图从哪里我的函数移动和保存字节。
请帮助我解决这个问题,因为正确理解我犯了什么错误对我来说很重要。
下面是使用函数transpose的c++代码

#include <iostream>
#include <windows.h>

extern "C" void transpose(INT64**, INT64);

// Function for displaying the matrix
void printMatrix(INT64** matrix, INT64 n) {
    for (INT64 i = 0; i < n; ++i) {
        for (INT64 j = 0; j < n; ++j) {
            std::cout << matrix[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

int main() {
    INT64 n = 8; // Matrix size

    // Initialization of matrix A
    INT64** A = new INT64 * [n];
    for (INT64 i = 0; i < n; ++i) {
        A[i] = new INT64[n];
        for (INT64 j = 0; j < n; ++j) {
            A[i][j] = i * n + j; // Filling matrix A
        }
    }

    std::cout << "Matrix before transposition:" << std::endl;
    printMatrix(A, n); // Display the matrix before transposition

    // Calling the transpose function
    transpose(A, n);

    std::cout << "Matrix after transposition:" << std::endl;
    printMatrix(A, n); // Display the matrix after transposition

    // Deallocate memory
    for (INT64 i = 0; i < n; ++i) {
        delete[] A[i];
    }
    delete[] A;

    return 0;
}

字符串
和这里转置函数

.code

transpose PROC
    mov r10, rax ; Store the dimension 8 in r10
    mov r11, rax ; Store the dimension 8 in r11

loopRow:
    mov r8, [rcx + rax]      ; Initialize the row index (i) to 8 (8,7,6,5,4,3,2,1)
    mov r9, [rcx + 8 * rax]      ; Initialize the column index (j) to 8 (56,48,40,32,24,16,8,0)

loopColumn:
    mov rdx, [r9 + rdi * 8] ; Load the element from the matrix (56,48,40,32,24,16,8,0)
    mov rsi, [rcx + rdi * 8] ; Load the element from the matrix (7,6,5,4,3,2,1,0)
    mov [r9 + rdi * 8], rsi ; Assign the element to the transposed location
    mov [rcx + rdi * 8], rdx
    inc rdi        ; Move to the next column
    cmp rdi, r10   ; Check if all columns are finished
    jl loopColumn
    inc r11        ; Move to the next row
    cmp rdi, r11   ; Check if all rows are finished
    jl loopRow

    ret
transpose ENDP

END


我觉得失败试图修复该代码在许多方面,但似乎我只是错过了一些重要的东西,而我的功能不工作
[编辑]
这是我的下一个代码,试图解决它:

.code

transpose PROC
    mov r10, rdx ; matrix size n
    mov r11, rdx ; matrix size n

loopRow:
    mov r10, r11
    mov r12, [rcx + 8 * r10 - 8] ; el.(64) of the matrix
    mov r13, [rcx + 8 * r11 - 8] ; el.(64) of the matrix

loopColumn:
    mov rdx, [rcx + 8 * r10 - 8]
    mov rsi, [rcx + 8 * r11 - 8]
    mov r8, rdx
    mov [rcx + 8 * r10 - 8], rsi
    mov [rcx + 8 * r11 - 8], rdx

    dec r10        ; Move to the next column
    jnz loopColumn
    dec r11        ; Move to the next row
    jnz loopRow

    ret
transpose ENDP
END

inn6fuwd

inn6fuwd1#

我看不出如何挽救现有的代码。

  • 你似乎在猜测论点在哪里。
  • 你使用RDI作为索引而没有预先初始化它。我想0是合适的,但即使这样,对列和行使用相同的缩放索引rdi * 8仍然是错误的。对于列,你需要一个步长为8(对应于inc rdi),但对于行,你需要一个步长为64(对应于add rdi, 8)。
  • 你用内存中的一些值(来自矩阵的元素)来设置R8和R9寄存器,在R8的情况下,你甚至不使用它。而对于R9,你使用数组中的元素,就像它是一个地址一样。
  • ...

前一段时间我发布了a Q/A on the codereview site。你应该读一下,因为它以图形方式显示了下面的代码。

; TransposeSquareMatrix(A, n)
    mov     rbx, rdi        ; Address A is in RDI
    mov     rcx, rsi        ; Dimension n is in RSI
    imul    r8, rsi, 8      ; Step between rows
    dec     rcx
    jz      .c              ; It's a (1 x 1) matrix
.a: push    rcx             ; (1)
    mov     rsi, rbx        ; Column address
    mov     rdi, rbx        ; Row address
.b: add     rsi, 8          ; To next element in this row
    add     rdi, r8         ; To next element in this column
    mov     rax, [rsi]      ; Swap 2 elements
    mov     rdx, [rdi]
    mov     [rdi], rax
    mov     [rsi], rdx
    dec     rcx
    jnz     .b
    lea     rbx, [rbx + r8 + 8] ; To next element on main diagonal
    pop     rcx             ; (1)
    dec     rcx
    jnz     .a              ; Continu until (1 x 1) matrix
.c: ret

字符串

相关问题