From 14d71a07dafa023ba83c2bdc6837d4ecc9de12ba Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Sun, 5 Oct 2025 22:07:40 -0700 Subject: hello works! yay Force-Push: yes Change-Id: I6c70991d16bd27da2b75ee0666203f043714a685 --- asm-notes.txt | 77 ++++++++++++++++++++++++++++++++++++++ exit-code.S | 27 -------------- exit-code.gnu.asm | 27 ++++++++++++++ hello.asm | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ quine.asm | 109 ------------------------------------------------------ 5 files changed, 208 insertions(+), 136 deletions(-) create mode 100644 asm-notes.txt delete mode 100644 exit-code.S create mode 100644 exit-code.gnu.asm create mode 100644 hello.asm delete mode 100644 quine.asm diff --git a/asm-notes.txt b/asm-notes.txt new file mode 100644 index 0000000..03bf335 --- /dev/null +++ b/asm-notes.txt @@ -0,0 +1,77 @@ + + + + ; opcode c7 is Ev, Iz. c6 is Eb, Ib + ; Eb: ModR/M to follow, byte + ; consider 1100 011w : 11 000 reg : imm + ; also consider 1011 w reg : imm for bytes + +32-bit target, 8-bit source + match =eax?, target + db 0xB8 + dd source + else match =edi?, target + db 0xBF + dd source + +64-bit target, 32-bit source + match =rax?, target ; mov rax, 0x1234 + db 0x48, 0xC7, 0xC0 + dd source +; 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) + + + + match =rdi, target ; mov rdi, 0x1234 + db 0x48, 0xC7, 0xC7 + dd source +; 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 + + + +64-bit target, 64-bi source + + match =rdi, target ; mov rdi, 0x1234 + db 0x48, 0xB8, 0x38 + dq source + + match =rsi, target + db 0x48, 0xB8, 0x30 + dq source + ; opcode c7 is Ev, Iz. c6 is Eb, Ib + ; Eb: ModR/M to follow, byte + ; consider 1100 011w : 11 000 reg : imm + ; also consider 1011 w reg : imm for bytes + diff --git a/exit-code.S b/exit-code.S deleted file mode 100644 index 4c723e8..0000000 --- a/exit-code.S +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file was a very early example, written by consulting [1]. It was - * useful primarily to see how the GNU assembler handles these opcodes, to - * better understand the encoding. - * - * [1] https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html - * - * - * gcc -o quine -nostartfiles -nostdlib quine.S && ./quine ; echo $? - * - * or - * - * as -o quine.o quine.S && ld -s -o quine quine.o && ./quine; echo $? - * - * Can't use nasm, nasm is 32-bit only. - */ -.text - -.global _start - -_start: - //mov $60, %rax - //mov $42, %rdi - mov $60, %eax - mov $42, %edi - syscall - diff --git a/exit-code.gnu.asm b/exit-code.gnu.asm new file mode 100644 index 0000000..4c723e8 --- /dev/null +++ b/exit-code.gnu.asm @@ -0,0 +1,27 @@ +/* + * This file was a very early example, written by consulting [1]. It was + * useful primarily to see how the GNU assembler handles these opcodes, to + * better understand the encoding. + * + * [1] https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html + * + * + * gcc -o quine -nostartfiles -nostdlib quine.S && ./quine ; echo $? + * + * or + * + * as -o quine.o quine.S && ld -s -o quine quine.o && ./quine; echo $? + * + * Can't use nasm, nasm is 32-bit only. + */ +.text + +.global _start + +_start: + //mov $60, %rax + //mov $42, %rdi + mov $60, %eax + mov $42, %edi + syscall + diff --git a/hello.asm b/hello.asm new file mode 100644 index 0000000..ed5dd57 --- /dev/null +++ b/hello.asm @@ -0,0 +1,104 @@ +; fasmg hello.asm hello && chmod 755 hello && ./hello; echo $? + +macro mov.d target, source + match =eax?, target + db 0xB8 + dd source + else match =edi?, target + db 0xBF + dd source + else match =rax?, target + db 0x48, 0xC7, 0xC0 + dd source + else match =rdi, target + db 0x48, 0xC7, 0xC7 + dd source + else + assert 0 + end match +end macro + + +macro mov.q target, source + match =rdi, target + db 0x48, 0xBF + dq source + else match =rsi, target + db 0x48, 0xBE + dq source + else match =rdx, target + db 0x48, 0xBA + dq source + else + assert 0 + end match +end macro + + +macro syscall + db 0x0F, 0x05 +; 0f two-byte escape +; 05 syscall ^ o64 +end macro + + + + +org 0x08048000 + +elf_header: +; * denotes mandatory fields according to breadbox + db 0x7F, "ELF" ; *magic number + 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 + ; required, but can be anything, subject to + ; alignment + dq 0 ; physical address (ignored) + dq file_size ; *size in file + dq file_size ; *size in memory + dq 0 ; segment alignment + ; for relocation - will we be ASLR'd? +program_header_entry_size = $ - program_header + +_start: + mov.d eax, 1 + mov.q rdi, 1 + mov.q rsi, greeting + mov.q rdx, greeting_size + syscall + + mov.d eax, 60 + mov.d edi, 0 + syscall + +greeting: + db "Hello, Irenes!", 0x0A +greeting_size = $ - greeting + +file_size = $ - $$ + diff --git a/quine.asm b/quine.asm deleted file mode 100644 index 9823d93..0000000 --- a/quine.asm +++ /dev/null @@ -1,109 +0,0 @@ -; fasmg quine.asm quine - -macro mov.d target, source - match =eax?, target - db 0xB8 - dd source - else match =edi?, target - db 0xBF - dd source - else 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: -; * denotes mandatory fields according to breadbox - db 0x7F, "ELF" ; *magic number - 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 - ; required, but can be anything, subject to - ; alignment - dq 0 ; physical address (ignored) - dq file_size ; *size in file - dq file_size ; *size in memory - dq 0 ; segment alignment - ; for relocation - will we be ASLR'd? -program_header_entry_size = $ - program_header - -_start: - mov.d eax, 60 - mov.d edi, 42 - syscall - -file_size = $ - $$ - -- cgit 1.4.1