99 lines
3.6 KiB
NASM
99 lines
3.6 KiB
NASM
; fasmg exit-code.asm exit-code
|
|
|
|
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 = $ - $$
|
|
|