; fasmg quine.asm quine macro mov.d target, source match =rax?, target db 0x48, 0xC7, 0xC0 ; 48 eAX REX.W prefix ; (DEC is the 32-bit meaning, ignore it) ; eAX -> register identifier, ; width depends on operand ; REX.W -> set 64-bit operand mode ; c7 Grp 11^1A - MOV Ev, Iz ; immediate to register ; 1A -> bits 5,4,3 of ModR/M are opcode ; extension ; E -> modR/M byte to follow for operand ; v -> word of appropriate size ; I -> immediate data ; z -> 32-bit operand ; c0 ModR/M byte ; 0b11000000 ; 11 mod: always 11 ; 000 op/reg: Mov Ev, Iz ; 00x w absent ; 0 w (ignored) dd source else match =rdi, target db 0x48, 0xC7, 0xC7 ; 7: 48 c7 c7 2a 00 00 00 mov $0x2a,%rdi ; 48 eAX REX.W prefix ; (DEC is the 32-bit meaning, ignore it) ; c7 Grp 11^1A - MOV Ev, Iz ; immediate to register ; 1A -> bits 5,4,3 of ModR/M are opcode ; extension ; Ev -> ModR/M to follow for 32-bit operand ; Iz -> Immediate data, 32-bits ; c7 ModR/M byte ; 0b11000111 ; 11 mod: always 11 ; 000 op/reg: Mov Ev, Iz ; 11x w present ; 1 w true; use EDI dd source end match end macro macro syscall db 0x0F, 0x05 ; 0f two-byte escape ; 05 syscall ^ o64 end macro org 0x08048000 elf_header: db 0x7F, "ELF" db 2 ; 64-bit db 1 ; little-endian db 1 ; ELF header format version 1 db 0 ; System-V ABI db 8 dup 0 ; (padding) dw 2 ; executable dw 0x3E ; Intel x86-64 dd 1 ; ELF format version dq _start ; entry point dq program_header - $$ ; program header offset dq 0 ; section header offset dd 0 ; processor flags dw elf_header_size dw program_header_entry_size dw 1 ; number of program header entries dw 0 ; section header entry size dw 0 ; number of section header entries dw 0 ; section name string table index elf_header_size = $ - elf_header program_header: dd 1 ; "loadable" segment type dd 0x05 ; read+execute permission dq 0 ; offset in file dq $$ ; virtual address dq 0 ; (padding) dq file_size ; size in file dq file_size ; size in memory dq 0 ; segment alignment program_header_entry_size = $ - program_header _start: mov.d rax, 60 mov.d rdi, 42 syscall file_size = $ - $$