두 행렬에 두 셀의 값을 더하는 C 프로그램을 작성 중입니다. 내 C 프로그램에서 두 셀을 추가하는 함수를 구현하는 Assembly 함수를 호출합니다. 이 함수에는 다음과 같은 서명이 있습니다.
// Adds two matrix cells together and returns the result
int addTwoCells(int **matrixA, int aRows, int aColumns, int cellARow, int cellAColumn,
int **matrixB, int bRows, int bColumns, int cellBRow, int cellBColumn);
아래는 내 C 프로그램 ( main.c
)입니다. 각 행렬의 오른쪽 아래 모서리가 3으로 설정된 동적 할당 3x3 행렬 2 개를 정의하고 있습니다. 함수 호출을 통해 오른쪽 아래 모서리를 추가하려고합니다.
#include <stdio.h>
#include <stdlib.h>
// Adds two matrix cells together and returns the result
int addTwoCells(int **matrixA, int aRows, int aColumns, int cellARow, int cellAColumn,
int **matrixB, int bRows, int bColumns, int cellBRow, int cellBColumn);
int main(void) {
// Define the dimensions for matrix A
int rA = 3;
int cA = 3;
// Define the double pointer that defines matrix A
int **matrixA;
// Dynamically allocate space for the entire matrix
matrixA = (int**) malloc(rA * sizeof(int*));
// Dynamically allocate sufficient space for each row in the entire matrix
for (int i = 0; i < rA; i++) {
matrixA[i] = (int*) malloc(cA * sizeof(int));
}
matrixA[2][2] = 3;
// Define the dimensions for matrix B
int rB = 3;
int cB = 3;
// Define the double pointer that defines matrix B
int **matrixB;
// Dynamically allocate space for the entire matrix
matrixB = (int**) malloc(rB * sizeof(int*));
// Dynamically allocate sufficient space for each row in the entire matrix
for (int i = 0; i < rB; i++) {
matrixB[i] = (int*) malloc(cB * sizeof(int));
}
matrixB[2][2] = 3;
// Test calling the matrix multiplication function using the static library
// compiled from the Assembly file
printf("%d\n", addTwoCells(matrixA, rA, cA, 2, 2, matrixB, rB, cB, 2, 2));
return EXIT_SUCCESS;
}
아래는 x86 어셈블리 프로그램 ( addTwoCells.s
)입니다. 먼저 모든 매개 변수를 처리 한 다음 첫 번째 행렬의 오른쪽 아래 모서리에있는 셀의 값을 검색하려고합니다. 이를 위해 먼저 오른쪽 하단 모서리에 해당하는 평면화 된 인덱스를 계산합니다 (디버깅 후 올바른 값 :) 2*(column count) + 2 = 2*3 + 2 = 8
. 그러나 평탄화 된 인덱스 + 첫 번째 행렬 ( matrixAStartingAddress
) 의 메모리 주소에서 정수를 검색하려고 하면 함수의 출력에 표시된 것처럼 3이어야 할 때 결과는 항상 미친 큰 숫자 (예 : 1478295976) 입니다. (EAX 레지스터에 저장 됨). 매개 변수를 올바르게 처리 하고 메모리 주소 자체가 아닌 %ecx
표현식을 통해 메모리 주소의 값을 이동하는 것처럼 보이기 때문에 이것은 이상하게 보입니다 (%ecx)
.
# Function signature:
# int addTwoMatrixCells(int **matrixA, int aRows, int aColumns, int cellARow, int cellAColumn,
# int **matrixB, int bRows, int BColumns, int cellBRow, int cellBColumn)
.data
# Matrix A dimensions
aRows:
.int 0
aColumns:
.int 0
# Coordinate of cell A
cellARow:
.int 0
cellAColumn:
.int 0
# Matrix B dimensions
bRows:
.int 0
bColumns:
.int 0
# Coordinate of cell B
cellBRow:
.int 0
cellBColumn:
.int 0
# The starting memory address of matrix A
matrixAStartingAddress:
.int 0
# The starting memory address of matrix B
matrixBStartingAddress:
.int 0
.text
# Defining a function addTwoMatrixCells
.global addTwoCells
addTwoCells:
# Prologue
push %ebp
movl %esp, %ebp
# Process in parameter 1: the starting memory address of matrix A
movl 8(%ebp), %ecx
movl %ecx, matrixAStartingAddress
# Process in parameter 2: the number of rows in matrix A
movl 12(%ebp), %ecx
movl %ecx, aRows
# Process in parameter 3: the number of columns in matrix A
movl 16(%ebp), %ecx
movl %ecx, aColumns
# Process in parameter 4: the row index of cellA
movl 20(%ebp), %ecx
movl %ecx, cellARow
# Process in parameter 5: the column index of cellA
movl 24(%ebp), %ecx
movl %ecx, cellAColumn
# Process in parameter 6: the number of rows in matrix B
movl 28(%ebp), %ecx
movl %ecx, bRows
# Process in parameter 7: the number of columns in matrix B
movl 32(%ebp), %ecx
movl %ecx, bColumns
# Process in parameter 8: the row index of cellB
movl 36(%ebp), %ecx
movl %ecx, cellBRow
# Process in parameter 9: the column index of cellB
movl 40(%ebp), %ecx
movl %ecx, cellBColumn
# Compute the flattened index of the cell in matrix A
# One of the arithmetic operators needs to be in a CUP register
# In this case, we designate ECX register to store the number of columns
# in matrix A (n) initially, but ECX after the computation will store
# the memory address of cellA in the matrix
movl aColumns, %ecx
imul cellARow, %ecx
addl cellAColumn, %ecx
addl matrixAStartingAddress, %ecx
movl (%ecx), %eax
# Compute the flattened index of the cell in matrix B
# Epilogue
movl %ebp, %esp
pop %ebp
ret
문제 1 : 매트릭스 B의 시작 메모리 주소를 잊어 버렸습니다. 매개 변수 6이어야하고 현재 매개 변수 6-9라고 부르는 것은 7-10이되어야합니다.
문제 2 : int
s는 x86에서 4 바이트 폭이지만 1 바이트 폭인 것처럼 셀 주소를 계산합니다.
문제 3 : C에서으로 이중 포인터를 전달하고 addTwoCells
있지만 어셈블리 코드는 2D 배열처럼 처리합니다. 호환되지 않는 유형입니다. 이 두 C 함수를 컴파일하고 결과 어셈블리를 비교해 보십시오 .
int readValuePtr(int rows, int cols, int cellRow, int cellCol, int **matrix) {
return matrix[cellRow][cellCol];
}
int readValueArr(int rows, int cols, int cellRow, int cellCol, int matrix[rows][cols]) {
return matrix[cellRow][cellCol];
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다