Hi, I just wanted to share this gist which shows how to write hello-world in ASM, in D.
D is very convenient for writing ASM! Here's what I got:
extern(C) int main()
{
auto hip = "hello D\n".ptr;
size_t len = 8;
// write(1, message, length)
asm {
mov RDX, len; // Buffer length
mov RSI, hip; // Message buffer
mov EDI, 1; // Stdout file descriptor (0x01)
mov RAX, 0x2000004; // write syscall number (0x01 on Linux)
syscall; // Make the syscall
}
return 0;
}
Compiling it with:
dmd -betterC -ofhello hello.d
Results in this on MacOS (Intel):
▶ objdump -d -M intel ./main
./main: file format mach-o 64-bit x86-64
Disassembly of section __TEXT,__text:
0000000100000fcc <_main>:
100000fcc: 55 push rbp
100000fcd: 48 8b ec mov rbp, rsp
100000fd0: 48 83 ec 10 sub rsp, 0x10
100000fd4: 48 8d 05 25 00 00 00 lea rax, [rip + 0x25] ## 0x100001000
100000fdb: 48 89 45 f0 mov qword ptr [rbp - 0x10], rax
100000fdf: 48 c7 45 f8 08 00 00 00 mov qword ptr [rbp - 0x8], 0x8
100000fe7: 48 8b 55 f8 mov rdx, qword ptr [rbp - 0x8]
100000feb: 48 8b 75 f0 mov rsi, qword ptr [rbp - 0x10]
100000fef: bf 01 00 00 00 mov edi, 0x1
100000ff4: b8 04 00 00 02 mov eax, 0x2000004
100000ff9: 0f 05 syscall
100000ffb: 31 c0 xor eax, eax
100000ffd: c9 leave
100000ffe: c3 ret
While I wrote the syscall number to RAX, objdump
shows it as eax
, not sure why?!
By the way: syscall numbers on MacOS are apparently unstable and the "correct" way to call the kernel is via C's stdlib.
Anyway, I thought this was cool and as I couldn't find anything much about ASM in D, I thought this may be useful to others.