NASM x86_64
1996fragletsystemsimperative.asm.s
docker run --rm --platform="linux/amd64" 100hellos/nasm-x86_64:latest
MCP + fragletc
MCPstdinargs
This language supports code execution via MCP and the fragletc CLI. Stdin piping and argument passing are both supported.
Install fragletc →NASM x86_64 is a systems imperative language first appearing in 1996.
Hello World
; ----------------------------------------------------------------------------------------
; Writes "Hello, World" to the console using only system calls. Runs on 64-bit Linux only.
; To assemble and run:
;
; nasm -felf64 hello.asm && ld hello.o && ./a.out
; ----------------------------------------------------------------------------------------
;
; Taken from https://cs.lmu.edu/~ray/notes/nasmtutorial/
;
global _start
section .text
_start:
; BEGIN_FRAGLET
mov rax, 1 ; system call for write
mov rdi, 1 ; file handle 1 is stdout
mov rsi, message ; address of string to output
mov rdx, 13 ; number of bytes
syscall ; invoke operating system to do the write
mov rax, 60 ; system call for exit
xor rdi, rdi ; exit code 0
syscall ; invoke operating system to exit
; END_FRAGLET
section .data
message: db "Hello World!", 10 ; note the newline at the endCoding Guide
Language Version
NASM 2.x (x86_64 assembly)
Execution Model
- Assembly language that must be assembled and linked
- Code is assembled with
nasm -felf64, then linked withld - Executes as a native x86_64 Linux binary
- Uses Linux system calls directly (syscall instruction)
Key Characteristics
- Low-level system programming
- Direct access to CPU registers (rax, rdi, rsi, rdx, etc.)
- Linux system call interface
- Manual memory management
- Case-sensitive
Fragment Authoring
Write valid x86_64 NASM assembly instructions. Your fragment becomes the _start section code. Your fragment will be assembled, linked, and executed.
System Calls
Common Linux x86_64 system calls:
- Write (1):
mov rax, 1; mov rdi, 1; mov rsi, address; mov rdx, length; syscall - Exit (60):
mov rax, 60; mov rdi, exit_code; syscall - Read (0):
mov rax, 0; mov rdi, 0; mov rsi, buffer; mov rdx, length; syscall
Registers
- rax: System call number / return value
- rdi: First argument (file descriptor, exit code)
- rsi: Second argument (buffer address)
- rdx: Third argument (buffer length)
- rcx, r8, r9: Additional arguments
- r10, r11: Temporary (may be clobbered by syscall)
Available Data
The message label in the .data section is available:
message: db "Hello World!", 10 ; 13 bytes totalCommon Patterns
- System call:
mov rax, <syscall_num>; mov rdi, <arg1>; mov rsi, <arg2>; mov rdx, <arg3>; syscall - Write to stdout:
mov rax, 1; mov rdi, 1; mov rsi, message; mov rdx, 13; syscall - Exit program:
mov rax, 60; xor rdi, rdi; syscall(exit code 0) - Exit with code:
mov rax, 60; mov rdi, <code>; syscall
Examples
; Basic write to stdout and exit
mov rax, 1 ; system call for write
mov rdi, 1 ; file handle 1 is stdout
mov rsi, message ; address of string to output
mov rdx, 13 ; number of bytes
syscall ; invoke operating system to do the write
mov rax, 60 ; system call for exit
xor rdi, rdi ; exit code 0
syscall ; invoke operating system to exit
; Exit with custom exit code
mov rax, 60 ; system call for exit
mov rdi, 42 ; exit code 42
syscall
; Minimal exit (no output)
mov rax, 60
mov rdi, 0
syscallCaveats
- Fragments must be valid x86_64 NASM assembly that assembles and links without errors
- Must end with an exit system call (mov rax, 60; syscall) or program will crash
- System call numbers are x86_64 Linux specific
- Register usage must follow x86_64 calling conventions
- The
messagelabel is available in the .data section (13 bytes: "Hello World!" + newline) - Assembly and linking happen fresh each time, so errors will fail execution
- Remember that this is raw assembly - no safety checks or error handling
Fraglet Scripts
Echo Args
#!/usr/bin/env -S fragletc --vein=nasm-x86_64
mov r12, [rsp]
mov r13, rsp
add r13, 8
mov rdi, 1
lea rsi, [rel args_prefix]
mov rdx, 6
mov rax, 1
syscall
cmp r12, 2
jl .done
mov r14, 1
.loop:
mov rsi, [r13 + r14*8]
xor rdx, rdx
.strlen:
cmp byte [rsi + rdx], 0
je .print
inc rdx
jmp .strlen
.print:
mov rdi, 1
mov rax, 1
syscall
inc r14
cmp r14, r12
jge .done
mov rdi, 1
lea rsi, [rel space_char]
mov rdx, 1
mov rax, 1
syscall
jmp .loop
.done:
lea rsi, [rel newline_char]
mov rdx, 1
mov rdi, 1
mov rax, 1
syscall
mov rax, 60
xor rdi, rdi
syscall
section .data
args_prefix: db "Args: "
space_char: db " "
newline_char: db 10Stdin Upper
#!/usr/bin/env -S fragletc --vein=nasm-x86_64
sub rsp, 64
mov rax, 0
mov rdi, 0
mov rsi, rsp
mov rdx, 64
syscall
mov rdx, rax
mov rax, 1
mov rdi, 1
mov rsi, rsp
syscall
add rsp, 64
mov rax, 60
xor rdi, rdi
syscallSyscall
#!/usr/bin/env -S fragletc --vein=nasm-x86_64
; Write existing message to stdout
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, message ; address of string (from template)
mov rdx, 13 ; length (13 bytes: "Hello World!" + newline)
syscall
; Exit with code 0
mov rax, 60
xor rdi, rdi ; exit code 0
syscallTest
#!/usr/bin/env -S fragletc --vein=nasm-x86_64
mov rax, 1 ; system call for write
mov rdi, 1 ; file handle 1 is stdout
mov rsi, message ; address of string to output
mov rdx, 13 ; number of bytes
syscall ; invoke operating system to do the write
mov rax, 60 ; system call for exit
xor rdi, rdi ; exit code 0
syscall ; invoke operating system to exitContainer Info
image100hellos/nasm-x86_64:latest
build scheduleFriday
fragletenabled
sourcenasm-x86_64/files/