Skip to content

Example snippet returns incorrect output when compiled without optimizations (x86) #1

Open
@illnyang

Description

@illnyang
Macro-expanded snippet from README.md (past-return code removed)
#include <stdio.h>
void __stdcall example(__int32 arg3);
unsigned __int32 __cdecl example_trampoline(__int32 arg, __int32 arg2, __int32 arg3);
void __stdcall example2();
void __cdecl example2_trampoline();

int main()
{
    int a = 1;
    int b = 3;
    printf("a = %d, b = %d\n", a, b);
    a = example_trampoline(a, 0, b);
    printf("a = %d, b = %d\n", a, b);
    example2_trampoline();
    return a;
}

void __stdcall example(__int32 arg3)
{
    __asm { push EAX }
    __asm { push EBX }
    __asm { push ECX }
    __asm { push EDI }
    __asm { push EDX }
    __asm { push ESI }

    __int32 arg;
    __asm { mov arg, eax }

    __int32 arg2;
    __asm { mov arg2, ebx }

    printf("arg = %d, arg3 = %d\n", arg, arg3);
    arg = arg + arg3;
    printf("arg = %d, arg3 = %d\n", arg, arg3);

    __asm { pop ESI }
    __asm { pop EDX }
    __asm { pop EDI }
    __asm { pop ECX }
    __asm { pop EBX }
    __asm { pop EAX }

    unsigned __int32 _usercall_internal_return_ = arg;
    __asm { mov eax, _usercall_internal_return_ }
    return;
}

unsigned __int32 __cdecl example_trampoline(__int32 arg, __int32 arg2, __int32 arg3) {
    __asm { mov eax, arg }
    __asm { mov ebx, arg2 }

    example(arg3);

    unsigned __int32 _usercall_internal_return_;
    __asm { mov _usercall_internal_return_, eax }
    return _usercall_internal_return_;
}

void __stdcall example2()
{
    __asm { push EAX }
    __asm { push EBX }
    __asm { push ECX }
    __asm { push EDI }
    __asm { push EDX }
    __asm { push ESI }
    printf("void function\n");
    __asm { pop ESI }
    __asm { pop EDX }
    __asm { pop EDI }
    __asm { pop ECX }
    __asm { pop EBX }
    __asm { pop EAX }
    return;
}

void __cdecl example2_trampoline()
{
    example2();
}
/DWIN32 /D_WINDOWS /EHsc /Zi /Ob0 /Od /RTC1 -MDd

a = 1, b = 3
arg = 3, arg3 = 3
arg = 6, arg3 = 3
a = 6, b = 3
void function

disasm @ godbolt

/DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -MD

a = 1, b = 3
arg = 1, arg3 = 3
arg = 4, arg3 = 3
a = 4, b = 3
void function

disasm @ godbolt

Microsoft (R) C/C++ Optimizing Compiler Version 19.30.30709 for x86

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions