100 Helloslanguages
Home / Languages / NASM x86_64

NASM x86_64

1996fraglet
systemsimperative.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 end

Coding 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 with ld
  • 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 total

Common 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
syscall

Caveats

  • 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 message label 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 10

Stdin 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
syscall

Syscall

#!/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
          syscall

Test

#!/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 exit

Container Info

image100hellos/nasm-x86_64:latest
build scheduleFriday
fragletenabled