Browse Source

Remove .align directive; add ASMData type.

master
Ben Kurtovic 9 years ago
parent
commit
52858aa2b5
4 changed files with 65 additions and 36 deletions
  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 View File

@@ -33,9 +33,9 @@ static ErrorInfo* parse_instruction(
/*
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)
{
@@ -53,32 +53,33 @@ static ErrorInfo* tokenize(AssemblerState *state)

while (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
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)) {
// TODO: add to symbol table
}
else {
if ((ei = parse_instruction(line, &inst, offset)))
goto error;
goto cleanup;

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

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

error:
asm_instructions_free(dummy.next);

cleanup:
state->instructions = dummy.next;
free(overlap_table);
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.
*/
@@ -208,10 +204,7 @@ size_t assemble(const LineBuffer *source, uint8_t **binary_ptr, ErrorInfo **ei_p
*ei_ptr = error_info;

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;
}



+ 4
- 5
src/assembler/directives.h View File

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

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

#define DIR_INCLUDE ".include"

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

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

#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) \
(DIRECTIVE_HAS_ARG(line, d) ? strlen(d) : 0)


+ 26
- 0
src/assembler/state.c View File

@@ -24,10 +24,23 @@ void state_init(AssemblerState *state)
state->lines = NULL;
state->includes = NULL;
state->instructions = NULL;
state->data = 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.
*/
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.
*/
void asm_symtable_free(ASMSymbolTable *symtable)


+ 11
- 0
src/assembler/state.h View File

@@ -42,6 +42,14 @@ struct 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 {
size_t offset;
char *symbol;
@@ -69,16 +77,19 @@ typedef struct {
ASMLine *lines;
ASMInclude *includes;
ASMInstruction *instructions;
ASMData *data;
ASMSymbolTable *symtable;
} AssemblerState;

/* Functions */

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

#ifdef DEBUG_MODE


Loading…
Cancel
Save