Tuesday, August 30, 2016

The end of __stdcall? Or Removing 16-bit compatibility?

    Reverse compatibility with __stdcall would end. More like its descendant, __fastcall, would try to replace it.

    However, __stdcall and __fastcall cannot deal with 2048-bit because the callee could only clean up 255 with return 255 bytes and 2048-bit entity is 256 bytes.

    Therefore,  __cdecl would win in the end, and the callee cleaning up the stack would be part of history or it would need to change the opcode so that a larger argument (not one byte argument limiting to 0-255 byte cleanup of the stack) would allow the callee to clean up the stack.


    Looks like compilers went with the removal of 16-bit compatibility by having __stdcall cleaning more than 255 bytes.

    Embedded 16-bit processor could only pop so much from stack, so they could only pop 255 bytes.

    x86 could pop 65535 bytes off of the stack.  So it could handle up to 262144-bit processors. 524288-bit entity is 65536 bytes.

    Compilers also have the option to adjust the stack pointer instead of using a RET imm assembly instruction.

    I've disassembled some programs, and functions that have void parameter usually passes two word size 0, so a function is best to pass two parameters. Best if the two parameters are structure pointers.

    Opcode Mnemonic Description
    C3 RET Near return to calling procedure.
    CB RET Far return to calling procedure.
    C2 iw RET imm16 Near return to calling procedure and pop imm16 bytes from stack.
    CA iw RET imm16 Far return to calling procedure and pop imm16 bytes from stack.

    Off topic:

    Many old compilers, before 2010, still have the 255 byte limit on their variable argument functions, totally unrelated to fixed argument functions.

    No comments: