Ассемблерная вставка на Си, ошибка Run-Time check failure #0 - Assembler
Формулировка задачи:
Здравствуйте! Помогите, пожалуйста, с реализацией ассемблерной вставки в Си. У меня есть программа на Си, нужно написать такую же программу в виде ассемблерной вставки (использую ассемблерный листинг сишной версии). Компилируется без ошибок, но потом выдает ошибку "Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention" Подскажите, пожалуйста, как исправить ошибку. Прилагаю Сишную программу и ее вариант на ассемблере
Ассемблерный вариант:
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<memory.h> #include <time.h> const int max_sqrt_n = 100000; const int S = 100000; bool nprime[max_sqrt_n], bloc[S]; int primes[max_sqrt_n], cnt; int main() { int n; scanf("%d", &n); clock_t start_time; start_time = clock(); int nsqrt = (int)sqrt((double)n); for (int i = 2; i <= nsqrt; ++i) if (!nprime[i]) { primes[cnt++] = i; if (i <= n) for (int j = i * i; j <= nsqrt; j += i) nprime[j] = true; } int result = 0; for (int k = 0, maxk = n / S; k <= maxk; ++k) { memset(bloc, 0, sizeof bloc); int start = k * S; for (int i = 0; i < cnt; ++i) { int start_idx = (start + primes[i] - 1) / primes[i]; int temp = start_idx < 2 ? 2 : start_idx; int j = temp * primes[i] - start; for (; j < S; j += primes[i]) bloc[j] = true; } if (k == 0) bloc[0] = bloc[1] = true; for (int i = 0; i < S && start + i <= n; ++i) if (!(bloc[i])) ++result; } start_time = clock() - start_time; printf("%d %.4lfs", result, (double)start_time / CLOCKS_PER_SEC); return 0; }
#include<stdlib.h> #include<stdio.h> #include<math.h> #include <time.h> #include <memory.h> #include <stdbool.h> #pragma function(memset) const int max_sqrt_n = 100000; const int S = 100000; bool nprime[max_sqrt_n]; bool bloc[S]; int primes[max_sqrt_n], cnt; const char fmt[] = "%d"; const char fmt1[] = " %.4lfs"; int main() { long long int c = CLOCKS_PER_SEC; int n, nsqrt, k, maxk; int result = 0; clock_t start_time; _asm { lea eax, n push eax push OFFSET fmt call DWORD PTR scanf add esp, 8 call dword ptr clock mov start_time, eax finit fild n fsqrt fist nsqrt mov edx, nsqrt mov ecx, 2 cmp edx, ecx jl LN57 mov edi, cnt LL22 : cmp nprime[ecx], 0 jne LN21 mov eax, ecx mov primes[edi * 4], ecx imul eax, ecx inc edi cmp eax, edx jg LN21 mov eax, ecx imul eax, ecx cmp eax, edx jg LN21 LL17 : mov nprime[eax], 1 add eax, ecx cmp eax, edx jle LL17 LN21 : inc ecx cmp ecx, edx jle LL22 mov cnt, edi mov edi, n LN57 : mov eax, 351843721 xor esi, esi imul edi mov ebx, esi mov result, esi sar edx, 13 mov eax, edx mov k, ebx shr eax, 31 add eax, edx mov maxk, eax js LN12 LL14 : push 100000 push 0 push offset bloc call memset xor edi, edi imul ebx, ebx, 100000 add esp, 12 cmp cnt, edi jle LN9 mov esi, cnt LL11 : mov ecx, primes[edi * 4] lea eax, [ebx - 1] add eax, ecx cdq idiv ecx mov edx, 2 cmp eax, 2 cmovl eax, edx imul eax, ecx sub eax, ebx cmp eax, 100000 jge LN10 LL8 : mov bloc[eax], 1 add eax, ecx cmp eax, 100000 jl LL8 LN10 : inc edi cmp edi, esi jl LL11 mov esi, result LN9 : cmp k, 0 jne LN5 mov bloc, 257 LN5 : mov edx, n mov edi, ebx xor ecx, ecx sub edi, OFFSET bloc LL4 : lea eax, bloc[ecx] add eax, edi cmp eax, edx jg LN13 cmp bloc[ecx], 0 jne LN3 inc esi LN3 : lea eax, [ebx + 1] add eax, ecx cmp eax, edx jg LN13 cmp bloc[ecx + 1], 0 jne LN43 inc esi LN43 : lea eax, [ebx + 2] add eax, ecx cmp eax, edx jg LN13 cmp bloc[ecx + 2], 0 jne LN45 inc esi LN45 : lea eax, [ebx + 3] add eax, ecx cmp eax, edx jg LN13 cmp bloc[ecx + 3], 0 jne LN47 inc esi LN47 : lea eax, [ebx + 4] add eax, ecx cmp eax, edx jg LN13 cmp bloc[ecx + 4], 0 jne LN49 inc esi LN49 : add ecx, 5 cmp ecx, 100000 jl LL4 LN13 : mov ebx, k inc ebx mov result, esi mov k, ebx cmp ebx, maxk jle LL14 LN12 : call DWORD PTR clock mov ebx, start_time sub eax, ebx sub esp, 8 mov start_time, eax fild dword ptr start_time fdiv dword ptr c fstp QWORD PTR[esp] push offset fmt call DWORD PTR printf sub esi, 1 push esi push OFFSET fmt1 call DWORD PTR printf add esp, 16 } return 0; }
Решение задачи: «Ассемблерная вставка на Си, ошибка Run-Time check failure #0»
textual
Листинг программы
void __stdcall pr(int a, int b) { printf("a - %d; b - %d ",a,b); } int _tmain(int argc, _TCHAR* argv[]) { int a = 5; int b = 6; __asm { push a push b call pr } return 0; }
Объяснение кода листинга программы
- В функции main() объявлены две переменные типа int — a и b, и инициализированы значениями 5 и 6 соответственно.
- В ассемблерном блоке кода происходит следующее: — В регистре ecx сохраняется значение переменной a. — В регистре edx сохраняется значение переменной b. — Вызывается функция pr() с помощью команды call, в стек заносятся адреса возврата и аргументов функции.
- В функции pr() происходит вывод значений переменных a и b в консоль с помощью функции printf().
- Значения переменных a и b соответствуют 5 и 6.
- Возвращаемое значение функции call pr() не используется.
- В функции main() возвращается 0, что означает успешный конец работы программы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д