Author Topic: How to produce very small 64-bit code  (Read 119 times)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 291
    • View Profile
    • zapsolution
How to produce very small 64-bit code
« on: April 01, 2017, 10:26:00 am »
You can reduce drastically the size of your 64-bit code if you follow these few steps.

1 - Always use direct call to the core FLAT API whenever available.
2 - Prefer procedural code when there is no need to use a class to achieve the same thing.
3 - Use explicit linking rather than implicit.
4 - Get free of the runtime Library, using Multi-threaded (/MT) in the code generation.

Here is an example on how to use explicit linking to MSVCRT to achieve ultimate granularity

Code: [Select]
#define long_proc typedef long (__stdcall *zProc)
#define void_proc typedef void (__stdcall *zProc)
#define double_proc typedef double (__stdcall *zProc)

#define M_LOG2E 1.44269504088896340736

HMODULE MSVCRT() {
    static HMODULE hModule;
    if (hModule == 0) { hModule = LoadLibrary(L"MSVCRT"); }
    return hModule;
}

double log2(IN double X) {
    double l2 = 0;
    HMODULE hModule = MSVCRT();
    if (hModule) {
        double_proc (double);
        zProc hProc = (zProc) GetProcAddress(hModule, "log");
        if (hProc) { l2 = hProc(X) * M_LOG2E; }
    }
    return l2;
}

void RandoMize(IN DWORD seed) {
    HMODULE hModule = MSVCRT();
    if (hModule) {
        void_proc (DWORD);
        zProc hProc = (zProc) GetProcAddress(hModule, "srand");
        if (hProc) { hProc(seed); }
    }
}

long Rand() {
    long nRand = 0;
    HMODULE hModule = MSVCRT();
    if (hModule) {
        long_proc ();
        zProc hProc = (zProc) GetProcAddress(hModule, "rand");
        if (hProc) { nRand = hProc(); }
    }
    return nRand;
}

size_t rnd(IN long nMin, IN long nMax) { // QWORD
    double dblRange = nMax - nMin;
    double dblMaxFactor = dblRange / RAND_MAX;
    double dblRandomNumber = (double) Rand();
    return (size_t) (nMin + dblMaxFactor * dblRandomNumber);
}

Rather than using the GDIPLUS class obscurification, see there how to call directly the FLAT API.

This is the technic i have used to produce the tiny OpenGL/TCLib visual plugins DLL used with MBox64, some being only 13 Kb in size !
« Last Edit: April 01, 2017, 03:38:18 pm by Patrice Terrier »

James Fuller

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: How to produce very small 64-bit code
« Reply #1 on: April 01, 2017, 10:46:52 am »
Patrice,
  As this is 64bit there is only one calling convention __fastcall?
Can the type be eliminated here ?
#define long_proc typedef long (__stdcall *zProc)

James


Patrice Terrier

  • Administrator
  • *****
  • Posts: 291
    • View Profile
    • zapsolution
Re: How to produce very small 64-bit code
« Reply #2 on: April 01, 2017, 03:00:03 pm »
James

You are right

Quote
Two important differences between x86 and x64 are the 64-bit addressing capability and a flat set of 16 64-bit registers for general use. Given the expanded register set, x64 uses the __fastcall calling convention and a RISC-based exception-handling model. The __fastcall convention uses registers for the first four arguments and the stack frame to pass additional arguments.
https://msdn.microsoft.com/en-us/library/ms235286.aspx

But i am using the same C++ source code to produce either 32 or 64-bit, and when creating a 32-bit DLL _stdcall is a mandatory to be compatible with the different languages i am using.

The use of stdcall has never had any impact on my 64-bit DLLs.
Read about it, on this MSDN link
https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx

It is like using a .def file for 32-bit, that is of no use for 64-bit.
« Last Edit: April 01, 2017, 03:21:14 pm by Patrice Terrier »