@Nordman99

Как правильно оформить inline вставку ассемблера в отдельный код для MASM?

Всем доброго дня! Может кто нибудь будет так добр что поможет по проблеме - возникла необходимость скомпилить кое какие исходники из гитхаба, но в 64 бита, если бы в 32 то проблем не возникло бы, опыт сборки и компиляции в MS Visual Studio уже имею, но правда в основном собирал и компилил в 32 бита, а тут вдруг столкнулся с проблемой - MS Visual Studio при компиляции в 64 бита не хочет работать с inline вставками ассемблерного кода в коде С/С++, нужно либо выносить этот код ассемблера в отдельный asm файл и оформлять его содержимое как функцию которая будет вызываться из кода С/С++, либо заменять ассемблерный код на его аналоги из команд intrinsic, с последним все еще менее понятно так что пока решил все делать первым способом, значит имеется на С++ вот такой код:
#include "StdCall.h"

#pragma runtime_checks( "s", off )
bool GetIsStdCallConvention(void* function, void* arg1, void** result)
{

    int stackLeftOver;
    int final;

    __asm
    {
     
        // Remember the stack pointer, so we can check if it got cleaned up.
        mov     stackLeftOver,  esp
        
        // Call the function.
        push    arg1
        call    function

        // Store the result.
        mov     final,          eax

        // Compute if the arguments were left on the stack by the function.
        mov     eax,            stackLeftOver
        sub     eax,            esp
        mov     stackLeftOver,  eax

        // Fix the stack.
        add     esp,            stackLeftOver

    }

    if (result)
    {
        *result = (void*)final;
    }

    // If anything was left on the stack after we called the function,
    // then it's the cdecl convention.
    return stackLeftOver == 0;


}
#pragma runtime_checks( "s", restore )


я его оформил примерно вот так:

#include "StdCall.h"

#pragma runtime_checks( "s", off )
bool GetIsStdCallConvention(void* function, void* arg1, void** result)
{

    int stackLeftOver;
    int final;
	
	extern "C"
{
    void Rememberthestackpointer1(int stackLeftOver, int final, arg1 );
}
	
    if (result)
    {
        *result = (void*)final;
    }

    // If anything was left on the stack after we called the function,
    // then it's the cdecl convention.
    return stackLeftOver == 0;


}
#pragma runtime_checks( "s", restore )


Код ассеблера оформил в другом asm файле примерно так:

.MODEL FLAT, C
.STACK

.DATA
.CODE
readName PROTO C
Rememberthestackpointer1 PROC stackLeftOver:DWORD final:DWORD arg1:DWORD
        mov     stackLeftOver,  esp
        push    arg1
        call    function
        mov     final,          eax
        mov     eax,            stackLeftOver
        sub     eax,            esp
        mov     stackLeftOver,  eax
        add     esp,            stackLeftOver
		ret
Rememberthestackpointer1 ENDP
END

В Ассемблере я сам чуть больше чем ноль поэтому прошу не ругаться, получается что в вызываемую функцию ассемблера Rememberthestackpointer1 из кода С++ надо передать три параметра - stackLeftOver, final и arg1, а в код ассемблера соответственно во 1ых должен быть правильно оформлен и должен правильно принять эти 3и параметра и вернуть обратно в код С++ результат, пожалуйста помогите все это правильно сделать
  • Вопрос задан
  • 413 просмотров
Решения вопроса 1
@none7
На x64 под виндой эта функция лишена смысла, поскольку стандартное соглашение вызовов не предполагает смещения стека для передачи параметров. Независимо от флагов stdcall/cdecl, компилятор использует fastcall.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы