N
N
Nordman992020-11-12 13:44:38
C++ / C#
Nordman99, 2020-11-12 13:44:38

How to arrange inline insertion of assembler into a separate code for MASM?

Good day everyone! Maybe someone will be so kind as to help with the problem - it became necessary to compile some sources from the github, but in 64 bits, if in 32 there would be no problems, I already have experience in building and compiling in MS Visual Studio, but the truth is mostly collected and compiled in 32 bits, and then suddenly ran into a problem - when compiling in 64 bits, MS Visual Studio does not want to work with inline inserts of assembler code in C / C ++ code, you either need to take this assembler code into a separate asm file and format it its contents as a function that will be called from the C / C ++ code, or replace the assembler code with its analogues from the intrinsic commands, with the latter it is still less clear, so for now I decided to do everything in the first way, so there is such a code in C ++ :

#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 )


I formatted it like this:

#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 )


I designed the assembler code in another asm file like this:

.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

In the assembler, I myself am a little more than zero, so please do not swear, it turns out that three parameters must be passed to the called Rememberthestackpointer1 assembler function from the C ++ code - stackLeftOver, final and arg1, and in the assembler code, respectively, in the 1st, it must be correctly formatted and must be correct accept these 3 parameters and return the result back to the C++ code, please help me to do all this correctly

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
none7, 2020-11-12
@Nordman99

On x64 under Windows, this function is meaningless, since the standard calling convention does not imply a stack offset for passing parameters. Regardless of the stdcall/cdecl flags, the compiler uses fastcall.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question