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.