diff options
| author | Andrew Chambers <[email protected]> | 2021-10-02 21:07:42 +1300 |
|---|---|---|
| committer | Andrew Chambers <[email protected]> | 2021-10-02 21:07:42 +1300 |
| commit | 58f3466bec7272be9783f6c7be19b5a5299212a0 (patch) | |
| tree | 79ed5461e4a965725f408f01a7b36fbf6ff8f754 | |
| parent | e12b5b927f5960d0583432e1aa07035295a6b660 (diff) | |
Assemble two instructions.
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | asmparser.peg | 11 | ||||
| -rw-r--r-- | dumbas.h (renamed from minias.h) | 20 | ||||
| -rw-r--r-- | main.c | 44 |
4 files changed, 66 insertions, 14 deletions
@@ -1,13 +1,12 @@ -# minias +# dumbas -An assembler for x86_64, written for fun and learning. +A dumb assembler for x86_64, written for fun and learning. Goals: - A simple, tiny, fast implementation (in that order). - Assemble the output of [cproc](https://github.com/michaelforney/cproc)/[qbe](https://c9x.me/compile/). - Relocatable elf output. -- Static linking only. Non Goals: diff --git a/asmparser.peg b/asmparser.peg new file mode 100644 index 0000000..77f90e5 --- /dev/null +++ b/asmparser.peg @@ -0,0 +1,11 @@ +%prefix "asmparser" + +%value "Parsev" + +program <- line* !. +line <- s:stmt eol { srcpos = $0s; onstmt(s); } +stmt <- i:instr { $$ = i; } +instr <- "nop" { $$.instr = (Instr){.kind = ASM_NOP}; } + / "ret" { $$.instr = (Instr){.kind = ASM_RET}; } +ws <- [ \t]* +eol <- ws ("\n" / ! .) @@ -5,6 +5,26 @@ #include <stdio.h> #include <unistd.h> +typedef struct { + Elf64_Shdr hdr; + size_t capacity; + uint8_t *data; +} Section; + +enum AsmKind { + ASM_NOP, + ASM_RET +}; + +typedef struct { + enum AsmKind kind; +} Instr; + +typedef union { + enum AsmKind kind; + Instr instr; +} Parsev; + static void die(char *s) { write(STDERR_FILENO, s, strlen(s)); exit(1); @@ -1,15 +1,12 @@ -#include "minias.h" +#include "dumbas.h" -typedef struct { - Elf64_Shdr hdr; - size_t capacity; - uint8_t *data; -} Section; +int srcpos = 0; #define MAXSECTIONS 32 static Section sections[MAXSECTIONS]; static size_t nsections = 1; // first is reserved. +static Section *cursection = NULL; static Section *shstrtab = NULL; static Section *strtab = NULL; static Section *symtab = NULL; @@ -25,6 +22,10 @@ static void secappend(Section *s, uint8_t *bytes, size_t n) { s->hdr.sh_size += n; } +static void secbyte(Section *s, uint8_t b) { + secappend(s, &b, 1); +} + static Elf64_Word elfstr(Section *sec, const char *s) { Elf64_Word i; for (i = 0; i < sec->hdr.sh_size; i++) { @@ -45,16 +46,14 @@ static Section *newsection() { } static void initsections(void) { - uint8_t zb = 0; - shstrtab = newsection(); - secappend(shstrtab, &zb, 1); + secbyte(shstrtab, 0); shstrtab->hdr.sh_name = elfstr(shstrtab, ".shstrtab"); shstrtab->hdr.sh_type = SHT_STRTAB; shstrtab->hdr.sh_entsize = 1; strtab = newsection(); - secappend(strtab, &zb, 1); + secbyte(strtab, 0); strtab->hdr.sh_name = elfstr(shstrtab, ".strtab"); strtab->hdr.sh_type = SHT_STRTAB; strtab->hdr.sh_entsize = 1; @@ -122,8 +121,31 @@ static void outelf(void) { } } -int main() { +void onstmt(Parsev p) { + switch (p.kind) { + case ASM_NOP: + secbyte(cursection, 0x90); + break; + case ASM_RET: + secbyte(cursection, 0xc3); + break; + default: + die("unexpected kind"); + } +} + +#include "asmparser.c" // XXX resolve dependency cycle. + +void parse(void) { + asmparser_context_t *ctx = asmparser_create(NULL); + while (asmparser_parse(ctx, NULL)); + asmparser_destroy(ctx); +} + +int main(void) { initsections(); + cursection = text; + parse(); outelf(); return 0; }
\ No newline at end of file |
