On Wednesday, 12 August 2015 at 22:18:41 UTC, Adam D. Ruppe wrote:
The way you'd typically do it on Windows is to just call one of the win32 api functions, similarly to how you'd do it from C or regular D, just calling the functions manually.

Here's an example:

import core.sys.windows.windows; // make the names of C funcs available

void main() {
    int written; // just let D handle the local var for us

    asm
    {
        // the goal is:
// WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), myhello.ptr, myhello.length, &written, null);

        // so call GetStdHandle first
        push STD_OUTPUT_HANDLE;
        call GetStdHandle;
        // the return value is now in EAX
        mov EBX, EAX; // save it for later in EBX

// we push arguments from right to left for the WriteConsoleA call..
        push 0; // null
        mov EAX, written; // local vars in D are available too
        push EAX; // &written
        push 13; // length of "HELLO, WORLD\n"
        lea EAX, myhello; // the address of our string
        push EAX; // pointer
        push EBX; // our saved handle from before
        call WriteConsoleA;
jmp past_hello; // need to jump past the string since it isn't actually executable code!
        myhello:
        db "HELLO, WORLD\n";
        past_hello:
        nop;
    }
}




That should run successfully.

Putting the string in a db like that isn't ideal either, you should probably just put it in an ordinary D variable too so the compiler can place it in the right place.

Then you can also load it. Since D asm complains about the .ptr property thinking it means an instruction, I would do something like:

string hello = "HELLO, WORLD\n";
auto myhello = hello.ptr;


Then you can just `mov EAX, myhello;` and it will work.

Reply via email to