Почему не работает код на ассемблере?

Рейтинг: 1Ответов: 1Опубликовано: 04.05.2023

Написал код на си с ассемблерными вставками, сначала вводил все переменные по отдельности, но потом решил упростить, с помощью макросов. Работать перестало, если у кого есть идеи как это изменить, то буду благодарен за помощь.

#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <math.h>

#define vvod (var, msg)\
_asm lea edx, msg\
_asm push edx\
_asm call printf\
_asm pop edx\
_asm lea eax, var\
_asm push eax\
_asm lea ebx\
_asm call scanf\
_asm add esp, 8

int main()
{
    int a, b, c, d, e;
    int y = 0;
    char R[] = "%s %d\n";
    char error[] = "error 0\n";
    char result[] = "result =";
    _asm {
            // a
            vvod(a, "a:")

            // b
            vvod(b, "b:")

            // c
            vvod(c, "c:")
            

            // d 
            vvod(d, "d:")

            jmp Ne_nol

            // e

    nol:
            lea edx, error
            push edx;
            call printf
            pop edx

    Ne_nol :
            vvod(e, "e:")

            mov ebx, e
            cmp ebx, 0
            je nol

            mov eax, a;
            sub eax, b;
            mov y, eax;
            mov eax, c
            imul d
            
            idiv e
            add eax, y

            push eax;
            lea edx, result;
            push edx;
            lea edx, R;
            push edx;
            call printf
            pop edx
            pop edx
            pop edx
    }
    getchar();
}

Вот старый код:

#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <math.h>
int main()
{
    int a, b, c, d, e;
    int y = 0;
    char I[] = "%i";
    char A[] = "a: ";
    char B[] = "b: ";
    char C[] = "c: ";
    char D[] = "d: ";
    char E[] = "e: ";
    char R[] = "%s %d\n";
    char error[] = "error 0\n";
    char result[] = "result =";
    _asm {
            lea edx, A
            push edx;
            call printf
            pop edx
            lea eax, a
            push eax
            lea ebx, I
            push ebx
            call scanf
            add esp, 8

            lea edx, B
            push edx;
            call printf
            pop edx
            lea eax, b
            push eax
            lea ebx, I
            push ebx
            call scanf
            add esp, 8

            lea edx, C
            push edx;
            call printf
            pop edx
            lea eax, c
            push eax
            lea ebx, I
            push ebx
            call scanf
            add esp, 8

            lea edx, D
            push edx;
            call printf
            pop edx
            lea eax, d
            push eax
            lea ebx, I
            push ebx
            call scanf
            add esp, 8
            jmp Ne_nol

    nol:
            lea edx, error
            push edx;
            call printf
            pop edx

    Ne_nol :
            lea edx, E
            push edx;
            call printf
            pop edx
            lea eax, e
            push eax
            lea ebx, I
            push ebx
            call scanf
            add esp, 8

            mov ebx, e
            cmp ebx, 0
            je nol

            mov eax, a;
            sub eax, b;
            mov y, eax;
            mov eax, c
            imul d
            
            idiv e
            add eax, y

            push eax;
            lea edx, result;
            push edx;
            lea edx, R;
            push edx;
            call printf
            pop edx
            pop edx
            pop edx
    }
    getchar();
}

Ответы

▲ 5Принят

Для начала вы бы убрали пробел в

#define vvod (var, msg)\

потому что иначе vvod раскрывается в (var, msg) и далее по тексту, в нечто вроде

char result[] = "result =";
_asm {
        (var, msg)_asm lea edx, msg_asm push edx_asm call printf_asm pop edx_asm ...

Но и убранный пробел не спасает, потому что макрос раскрывается в одну строку без пробелов:

char result[] = "result =";
_asm {
        _asm lea edx, msg_asm push edx_asm call printf_asm pop edx_asm lea eax, ...

Как вы, надеюсь, понимаете, этот синтаксис не вписывается в рамки ассемблерных вставок.

P.S. Каким компилятором пользуетесь? Например, в VC++ ключик /E позволяет посмотреть, что препроцессор делает с исходниками. Очень способствует пониманию...

Update

Читаем внимательно этот текст и пишем макрос правильно:

#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <math.h>

#define vvod(var,msg) \
__asm lea edx, msg \
__asm push edx \
__asm call printf \
__asm pop edx \
__asm lea eax, var \
__asm push eax \
__asm lea ebx, I \
__asm call scanf \
__asm add esp, 8


int main()
{
    int a, b, c, d, e;
    int y = 0;

    char I[] = "%i";
    char A[] = "a: ";
    char B[] = "b: ";
    char C[] = "c: ";
    char D[] = "d: ";
    char E[] = "e: ";
    char R[] = "%s %d\n";
    char error[] = "error 0\n";
    char result[] = "result =";

    _asm {
            // a
            vvod(a,A)

            // b
            vvod(b,B)

            // c
            vvod(c,C)
            

            // d 
            vvod(d, D)

            jmp Ne_nol

            // e

    nol:
            lea edx, error
            push edx;
            call printf
            pop edx

    Ne_nol :
            vvod(e, E)

            mov ebx, e
            cmp ebx, 0
            je nol

            mov eax, a;
            sub eax, b;
            mov y, eax;
            mov eax, c
            imul d
            
            idiv e
            add eax, y

            push eax;
            lea edx, result;
            push edx;
            lea edx, R;
            push edx;
            call printf
            pop edx
            pop edx
            pop edx
    }
    getchar();
}