Kaynağa Gözat

Remove .align directive; add ASMData type.

master
Ben Kurtovic 9 yıl önce
ebeveyn
işleme
52858aa2b5
4 değiştirilmiş dosya ile 65 ekleme ve 36 silme
  1. +24
    -31
      src/assembler.c
  2. +4
    -5
      src/assembler/directives.h
  3. +26
    -0
      src/assembler/state.c
  4. +11
    -0
      src/assembler/state.h

+ 24
- 31
src/assembler.c Dosyayı Görüntüle

@@ -33,9 +33,9 @@ static ErrorInfo* parse_instruction(
/* /*
Tokenize ASMLines into ASMInstructions. Tokenize ASMLines into ASMInstructions.


On success, state->instructions is modified and NULL is returned. On error,
an ErrorInfo object is returned and state->instructions is not modified.
state->symtable may or may not be modified regardless of success.
NULL is returned on success and an ErrorInfo object is returned on failure.
state->instructions, state->data, and state->symtable may or may not be
modified regardless of success.
*/ */
static ErrorInfo* tokenize(AssemblerState *state) static ErrorInfo* tokenize(AssemblerState *state)
{ {
@@ -53,32 +53,33 @@ static ErrorInfo* tokenize(AssemblerState *state)


while (line) { while (line) {
if (IS_LOCAL_DIRECTIVE(line)) { if (IS_LOCAL_DIRECTIVE(line)) {
if (!IS_DIRECTIVE(line, DIR_ORIGIN)) {
if (IS_DIRECTIVE(line, DIR_ORIGIN)) {
if (!DIRECTIVE_HAS_ARG(line, DIR_ORIGIN)) {
ei = error_info_create(line, ET_PREPROC, ED_PP_NO_ARG);
goto cleanup;
}

uint32_t arg;
if (!parse_uint32_t(&arg, line, DIR_ORIGIN)) {
ei = error_info_create(line, ET_PREPROC, ED_PP_BAD_ARG);
goto cleanup;
}

offset = arg;
origin = line;
}
else {
// TODO // TODO
ei = error_info_create(line, ET_PREPROC, ED_PP_UNKNOWN); ei = error_info_create(line, ET_PREPROC, ED_PP_UNKNOWN);
goto error;
}

if (!DIRECTIVE_HAS_ARG(line, DIR_ORIGIN)) {
ei = error_info_create(line, ET_PREPROC, ED_PP_NO_ARG);
goto error;
goto cleanup;
} }

uint32_t arg;
if (!parse_uint32_t(&arg, line, DIR_ORIGIN)) {
ei = error_info_create(line, ET_PREPROC, ED_PP_BAD_ARG);
goto error;
}

offset = arg;
origin = line;
} }
else if (IS_LABEL(line)) { else if (IS_LABEL(line)) {
// TODO: add to symbol table // TODO: add to symbol table
} }
else { else {
if ((ei = parse_instruction(line, &inst, offset))) if ((ei = parse_instruction(line, &inst, offset)))
goto error;
goto cleanup;


// TODO: bounded check on range [offset, offset + inst->length) against overlap table // TODO: bounded check on range [offset, offset + inst->length) against overlap table
// if clash, use error with current line, // if clash, use error with current line,
@@ -92,13 +93,8 @@ static ErrorInfo* tokenize(AssemblerState *state)
line = line->next; line = line->next;
} }


state->instructions = dummy.next;
goto cleanup;

error:
asm_instructions_free(dummy.next);

cleanup: cleanup:
state->instructions = dummy.next;
free(overlap_table); free(overlap_table);
return ei; return ei;
} }
@@ -144,7 +140,7 @@ static ErrorInfo* resolve_symbols(AssemblerState *state)
} }


/* /*
Convert finalized ASMInstructions into a binary data block.
Convert finalized ASMInstructions and ASMData into a binary data block.


This function should never fail. This function should never fail.
*/ */
@@ -208,10 +204,7 @@ size_t assemble(const LineBuffer *source, uint8_t **binary_ptr, ErrorInfo **ei_p
*ei_ptr = error_info; *ei_ptr = error_info;


cleanup: cleanup:
asm_lines_free(state.lines);
asm_includes_free(state.includes);
asm_instructions_free(state.instructions);
asm_symtable_free(state.symtable);
state_free(&state);
return retval; return retval;
} }




+ 4
- 5
src/assembler/directives.h Dosyayı Görüntüle

@@ -6,7 +6,7 @@
#include <string.h> #include <string.h>


#define DIRECTIVE_MARKER '.' #define DIRECTIVE_MARKER '.'
#define NUM_DIRECTIVES 15
#define NUM_DIRECTIVES 14


#define DIR_INCLUDE ".include" #define DIR_INCLUDE ".include"


@@ -20,7 +20,6 @@
#define DIR_ROM_DECLSIZE ".rom_declsize" #define DIR_ROM_DECLSIZE ".rom_declsize"


#define DIR_ORIGIN ".org" #define DIR_ORIGIN ".org"
#define DIR_ALIGN ".align"
#define DIR_BYTE ".byte" #define DIR_BYTE ".byte"
#define DIR_ASCII ".ascii" #define DIR_ASCII ".ascii"
#define DIR_ASCIZ ".asciz" #define DIR_ASCIZ ".asciz"
@@ -34,9 +33,9 @@
(!DIRECTIVE_HAS_ARG(line, d) || (line)->data[strlen(d)] == ' ')) (!DIRECTIVE_HAS_ARG(line, d) || (line)->data[strlen(d)] == ' '))


#define IS_LOCAL_DIRECTIVE(line) \ #define IS_LOCAL_DIRECTIVE(line) \
(IS_DIRECTIVE(line, DIR_ORIGIN) || IS_DIRECTIVE(line, DIR_ALIGN) || \
IS_DIRECTIVE(line, DIR_BYTE) || IS_DIRECTIVE(line, DIR_ASCII) || \
IS_DIRECTIVE(line, DIR_ASCIZ) || IS_DIRECTIVE(line, DIR_ASCIIZ))
(IS_DIRECTIVE(line, DIR_ORIGIN) || IS_DIRECTIVE(line, DIR_BYTE) || \
IS_DIRECTIVE(line, DIR_ASCII) || IS_DIRECTIVE(line, DIR_ASCIZ) || \
IS_DIRECTIVE(line, DIR_ASCIIZ))


#define DIRECTIVE_OFFSET(line, d) \ #define DIRECTIVE_OFFSET(line, d) \
(DIRECTIVE_HAS_ARG(line, d) ? strlen(d) : 0) (DIRECTIVE_HAS_ARG(line, d) ? strlen(d) : 0)


+ 26
- 0
src/assembler/state.c Dosyayı Görüntüle

@@ -24,10 +24,23 @@ void state_init(AssemblerState *state)
state->lines = NULL; state->lines = NULL;
state->includes = NULL; state->includes = NULL;
state->instructions = NULL; state->instructions = NULL;
state->data = NULL;
state->symtable = NULL; state->symtable = NULL;
} }


/* /*
Deallocate the contents of an AssemblerState object.
*/
void state_free(AssemblerState *state)
{
asm_lines_free(state->lines);
asm_includes_free(state->includes);
asm_instructions_free(state->instructions);
asm_data_free(state->data);
asm_symtable_free(state->symtable);
}

/*
Initialize an ASMSymbolTable and place it in *symtable_ptr. Initialize an ASMSymbolTable and place it in *symtable_ptr.
*/ */
void asm_symtable_init(ASMSymbolTable **symtable_ptr) void asm_symtable_init(ASMSymbolTable **symtable_ptr)
@@ -83,6 +96,19 @@ void asm_instructions_free(ASMInstruction *inst)
} }


/* /*
Deallocate an ASMData list.
*/
void asm_data_free(ASMData *data)
{
while (data) {
ASMData *temp = data->next;
free(data->data);
free(data);
data = temp;
}
}

/*
Deallocate an ASMSymbolTable. Deallocate an ASMSymbolTable.
*/ */
void asm_symtable_free(ASMSymbolTable *symtable) void asm_symtable_free(ASMSymbolTable *symtable)


+ 11
- 0
src/assembler/state.h Dosyayı Görüntüle

@@ -42,6 +42,14 @@ struct ASMInstruction {
}; };
typedef struct ASMInstruction ASMInstruction; typedef struct ASMInstruction ASMInstruction;


struct ASMData {
size_t offset;
size_t length;
uint8_t *data;
struct ASMData *next;
};
typedef struct ASMData ASMData;

struct ASMSymbol { struct ASMSymbol {
size_t offset; size_t offset;
char *symbol; char *symbol;
@@ -69,16 +77,19 @@ typedef struct {
ASMLine *lines; ASMLine *lines;
ASMInclude *includes; ASMInclude *includes;
ASMInstruction *instructions; ASMInstruction *instructions;
ASMData *data;
ASMSymbolTable *symtable; ASMSymbolTable *symtable;
} AssemblerState; } AssemblerState;


/* Functions */ /* Functions */


void state_init(AssemblerState*); void state_init(AssemblerState*);
void state_free(AssemblerState*);
void asm_symtable_init(ASMSymbolTable**); void asm_symtable_init(ASMSymbolTable**);
void asm_lines_free(ASMLine*); void asm_lines_free(ASMLine*);
void asm_includes_free(ASMInclude*); void asm_includes_free(ASMInclude*);
void asm_instructions_free(ASMInstruction*); void asm_instructions_free(ASMInstruction*);
void asm_data_free(ASMData*);
void asm_symtable_free(ASMSymbolTable*); void asm_symtable_free(ASMSymbolTable*);


#ifdef DEBUG_MODE #ifdef DEBUG_MODE


Yükleniyor…
İptal
Kaydet