summaryrefslogtreecommitdiff
path: root/masm
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-09-11 12:47:27 -0400
committerFreya Murphy <freya@freyacat.org>2024-09-11 12:47:27 -0400
commitc1a44ed41dcf92d1567ab927d7f1675d6918aff9 (patch)
treea9c385264b6a52087856addf568c941c56a5800d /masm
parentrefactor (diff)
downloadmips-c1a44ed41dcf92d1567ab927d7f1675d6918aff9.tar.gz
mips-c1a44ed41dcf92d1567ab927d7f1675d6918aff9.tar.bz2
mips-c1a44ed41dcf92d1567ab927d7f1675d6918aff9.zip
add ascii and asciiz directives, fix symtab bug
Diffstat (limited to '')
-rw-r--r--masm/asm.c20
-rw-r--r--masm/asm.h3
-rw-r--r--masm/parse.c20
-rw-r--r--masm/parse.h30
-rw-r--r--masm/symtab.c2
-rw-r--r--masm/test.asm5
6 files changed, 76 insertions, 4 deletions
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 <elf.h>
#include <mips.h>
+#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 <mips.h>
#include <stdint.h>
-///
-/// 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