Ассемблерная вставка на Си, ошибка 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;
}

Объяснение кода листинга программы

  1. В функции main() объявлены две переменные типа int — a и b, и инициализированы значениями 5 и 6 соответственно.
  2. В ассемблерном блоке кода происходит следующее: — В регистре ecx сохраняется значение переменной a. — В регистре edx сохраняется значение переменной b. — Вызывается функция pr() с помощью команды call, в стек заносятся адреса возврата и аргументов функции.
  3. В функции pr() происходит вывод значений переменных a и b в консоль с помощью функции printf().
  4. Значения переменных a и b соответствуют 5 и 6.
  5. Возвращаемое значение функции call pr() не используется.
  6. В функции main() возвращается 0, что означает успешный конец работы программы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 3.273 из 5
Похожие ответы