#cpp #c #visual_studio #ассемблер #visual_studio_2010
При выполнении этого кода получаю следующую ошибку: Run-Time Check Failure #2 - Stack around the variable 'C' was corrupted. Сам код: #include#include #include #define SIZE_ROW 1000 #define SIZE_COLUMN 8 #ifndef BYTE #define BYTE typedef unsigned char byte; #endif void init(byte* A) { for (long long int i = 0; i < (SIZE_ROW * SIZE_COLUMN); i++) { A[i] = rand() + 5*i + 9; } } void MyAsm(byte* A, byte* B, byte* C, byte k) { byte lastRes = 0; _asm { pusha ;init mov ecx, SIZE_ROW*SIZE_COLUMN xor esi, esi loop1: mov bl, byte ptr B[esi] mov al, k mov dl, byte ptr C[esi] imul dl ;k*C add al, bl ;b+k*C mov byte ptr A[esi], al mov lastRes, al inc esi loop loop1 popa } std::cout << ("Последний результат из ассемблера: " + std::to_string((long long)lastRes)); } int main() { srand(time(NULL)); byte A[SIZE_ROW * SIZE_COLUMN], B[SIZE_ROW * SIZE_COLUMN], C[SIZE_ROW * SIZE_COLUMN]; byte k = 2; init(B); init(C); MyAsm(A, B, C, k); return 0; } При этом если поместить тело функции MyAsm в main(), то всё нормально работает. В чем может быть ошибка и как ее исправить? Компилятор: Microsoft Visual Studio 2010 Professtional ОС: Windows 10 Pro x64 Сама задача: вычислить значение выражения A = B + k*C, где k - постоянный коэффециент, а A, B, C - матрицы одинаковых размеров. При этом нужно сделать через ассемблерную вставку.
Ответы
Ответ 1
Инструкции типа mov byte ptr A[esi], al записывают данные в память самой локальной переменной A со смещением esi. То есть это даже близко не является записью в память, указуемую указателем A (как вы, очевидно, хотели). В результате вместо доступа к своим массивам вы разрушаете значение A, а затем и стек вашей функции MyAsm. Чтобы доступиться к памяти массива, переданного через указатель A, вам надо прочитать содержимое A в регистр и адресоваться уже от него. Аналогично со всеми остальными указателями. То есть если делать "в лоб" то например так mov edi, B mov bl, byte ptr [edi + esi] mov edi, C mov dl, byte ptr [edi + esi] ... mov edi, A mov byte ptr [edi + esi], al Разумеется, аккуратно манипулируя регистрами, вы можете избежать постоянного чтения значений A, B и С из памяти.
Комментариев нет:
Отправить комментарий