From c1a44ed41dcf92d1567ab927d7f1675d6918aff9 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Wed, 11 Sep 2024 12:47:27 -0400 Subject: [PATCH] add ascii and asciiz directives, fix symtab bug --- include/mips.h | 26 -------------------------- masm/asm.c | 20 ++++++++++++++++++++ masm/asm.h | 3 +++ masm/parse.c | 20 ++++++++++++++++++++ masm/parse.h | 30 +++++++++++++++++++++++++++--- masm/symtab.c | 2 +- masm/test.asm | 5 +++++ 7 files changed, 76 insertions(+), 30 deletions(-) diff --git a/include/mips.h b/include/mips.h index 8d76d12..1233693 100644 --- a/include/mips.h +++ b/include/mips.h @@ -475,30 +475,4 @@ MIPS_INS(XORI, I, .op = MIPS_OP_XORI) #undef MIPS_INS -/* mips directive types */ -enum mips_directive_type { - MIPS_DIRECTIVE_ALIGN, - MIPS_DIRECTIVE_SPACE, - MIPS_DIRECTIVE_WORD, - MIPS_DIRECTIVE_HALF, - MIPS_DIRECTIVE_BYTE, - MIPS_DIRECTIVE_SECTION, - MIPS_DIRECTIVE_EXTERN, - MIPS_DIRECTIVE_GLOBL, -}; - -/* mip32 directive */ -struct mips_directive { - enum mips_directive_type type; - uint32_t len; // used for words, halfs, bytes - union { - uint16_t align; - uint16_t space; - uint32_t words[MAX_ARG_LENGTH]; - uint16_t halfs[MAX_ARG_LENGTH]; - uint8_t bytes[MAX_ARG_LENGTH]; - char name[MAX_ARG_LENGTH]; - }; -}; - #endif /* __MIPS_H__ */ diff --git a/masm/asm.c b/masm/asm.c index 54d766b..a9cee99 100644 --- a/masm/asm.c +++ b/masm/asm.c @@ -165,6 +165,26 @@ static int handle_directive(struct assembler *assembler, break; } + + case MIPS_DIRECTIVE_ASCII: { + struct section_entry entry; + entry.type = ENT_STR; + entry.size = strlen(directive->name); + memcpy(entry.str, directive->name, entry.size); + if (sec_push(assembler->sectab.current, entry)) + return M_ERROR; + break; + } + + case MIPS_DIRECTIVE_ASCIIZ: { + struct section_entry entry; + entry.type = ENT_STR; + entry.size = strlen(directive->name) + 1; + memcpy(entry.str, directive->name, entry.size); + if (sec_push(assembler->sectab.current, entry)) + return M_ERROR; + break; + } } return M_SUCCESS; diff --git a/masm/asm.h b/masm/asm.h index c8a6394..267aa1c 100644 --- a/masm/asm.h +++ b/masm/asm.h @@ -7,6 +7,7 @@ #include #include +#include "mlimits.h" #include "parse.h" #include "lex.h" @@ -102,6 +103,7 @@ enum section_entry_type { ENT_WORD, ENT_HALF, ENT_BYTE, + ENT_STR, ENT_NO_DATA, }; @@ -117,6 +119,7 @@ struct section_entry { // data struct mips_instruction ins; + char str[MAX_LEX_LENGTH]; int32_t word; int16_t half; int8_t byte; diff --git a/masm/parse.c b/masm/parse.c index ccabf41..2a84a91 100644 --- a/masm/parse.c +++ b/masm/parse.c @@ -875,6 +875,20 @@ static int parse_directive_globl(struct parser *parser, return M_SUCCESS; } +static int parse_directive_ascii(struct parser *parser, + struct mips_directive *directive, + enum mips_directive_type type) +{ + struct token token; + if (assert_token(parser, TOK_STRING, &token)) + return M_ERROR; + + directive->type = type; + strcpy(directive->name, token.text); + + return M_SUCCESS; +} + static int parse_section(struct mips_directive *directive, char name[MAX_LEX_LENGTH]) { @@ -909,6 +923,12 @@ static int parse_directive(struct parser *parser, return parse_directive_extern(parser, directive); else if (strcmp(token.text, "globl") == 0) return parse_directive_globl(parser, directive); + else if (strcmp(token.text, "ascii") == 0) + return parse_directive_ascii(parser, directive, + MIPS_DIRECTIVE_ASCII); + else if (strcmp(token.text, "asciiz") == 0) + return parse_directive_ascii(parser, directive, + MIPS_DIRECTIVE_ASCIIZ); else return parse_section(directive, token.text); } diff --git a/masm/parse.h b/masm/parse.h index 9181899..3052d51 100644 --- a/masm/parse.h +++ b/masm/parse.h @@ -9,9 +9,33 @@ #include #include -/// -/// reference -/// +/* mips directive types */ +enum mips_directive_type { + MIPS_DIRECTIVE_ALIGN, + MIPS_DIRECTIVE_SPACE, + MIPS_DIRECTIVE_WORD, + MIPS_DIRECTIVE_HALF, + MIPS_DIRECTIVE_BYTE, + MIPS_DIRECTIVE_SECTION, + MIPS_DIRECTIVE_EXTERN, + MIPS_DIRECTIVE_GLOBL, + MIPS_DIRECTIVE_ASCII, + MIPS_DIRECTIVE_ASCIIZ, +}; + +/* mip32 directive */ +struct mips_directive { + enum mips_directive_type type; + uint32_t len; // used for words, halfs, bytes + union { + uint16_t align; + uint16_t space; + uint32_t words[MAX_ARG_LENGTH]; + uint16_t halfs[MAX_ARG_LENGTH]; + uint8_t bytes[MAX_ARG_LENGTH]; + char name[MAX_ARG_LENGTH]; + }; +}; enum reference_type { REF_NONE, diff --git a/masm/symtab.c b/masm/symtab.c index 7d40609..897c4f9 100644 --- a/masm/symtab.c +++ b/masm/symtab.c @@ -61,7 +61,7 @@ int symtab_find(struct symbol_table *symtab, Elf32_Sym **ptr, ptrdiff_t diff = sym - symtab->symbols; if (idx != NULL) - *idx = diff / sizeof(Elf32_Sym); + *idx = diff; return M_SUCCESS; } diff --git a/masm/test.asm b/masm/test.asm index 1820b62..3dea7c9 100644 --- a/masm/test.asm +++ b/masm/test.asm @@ -1,3 +1,8 @@ +.data + +str: +.ascii "hello world" + .text .align 2