From 391b6e0958be1f6d00c5f3c7e57fee87bec965ef Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 31 May 2020 15:02:46 +0200 Subject: added support for multi-operand db in asm-i386 for string definitions added string and character tests --- ecomp-c/asm-i386.c | 45 +++++--- ecomp-c/ec.c | 44 +++++--- ecomp-c/minie.ebnf | 4 +- ecomp-c/test.sh | 2 + ecomp-c/tests/asm-i386/mov.asm | 1 + ecomp-c/tests/character_variable.e | 15 +++ ecomp-c/tests/character_variable.easm | 14 +++ ecomp-c/tests/character_variable.easm_err | 0 ecomp-c/tests/character_variable.ecomp_err | 0 ecomp-c/tests/character_variable.erun | 158 +++++++++++++++++++++++++++++ ecomp-c/tests/string_variable.e | 16 +++ ecomp-c/tests/string_variable.easm | 11 ++ ecomp-c/tests/string_variable.easm_err | 0 ecomp-c/tests/string_variable.ecomp_err | 0 ecomp-c/tests/string_variable.erun | 48 +++++++++ 15 files changed, 325 insertions(+), 33 deletions(-) create mode 100644 ecomp-c/tests/character_variable.e create mode 100644 ecomp-c/tests/character_variable.easm create mode 100644 ecomp-c/tests/character_variable.easm_err create mode 100644 ecomp-c/tests/character_variable.ecomp_err create mode 100644 ecomp-c/tests/character_variable.erun create mode 100644 ecomp-c/tests/string_variable.e create mode 100644 ecomp-c/tests/string_variable.easm create mode 100644 ecomp-c/tests/string_variable.easm_err create mode 100644 ecomp-c/tests/string_variable.ecomp_err create mode 100644 ecomp-c/tests/string_variable.erun diff --git a/ecomp-c/asm-i386.c b/ecomp-c/asm-i386.c index fd4ab1a..ba62fc8 100644 --- a/ecomp-c/asm-i386.c +++ b/ecomp-c/asm-i386.c @@ -48,7 +48,7 @@ * use32 * org 0x0000 * dd 0x0000 - * db 0x00 + * db 0x00 (1 to N arguments), combinable with string literals * db "abcd" */ @@ -214,8 +214,14 @@ static int isHexDigit( int c ) static int isSpecial( int c ) { - if( c == '_' ) return 1; - return 0; + switch( c ) { + case '_': + case ' ': + return 1; + + default: + return 0; + } } static void skipWhite( void ) @@ -302,11 +308,11 @@ static void identifier( void ) { int n = 0; - if( isAlpha( look ) || isSpecial( look ) ) { + if( isAlpha( look ) || ( look == '_' ) ) { ident[n] = look; n++; look = getChar( ); - while( ( isAlpha( look ) || isDigit( look ) || isSpecial( look ) ) && n < MAX_IDENT_LEN ) { + while( ( isAlpha( look ) || isDigit( look ) || ( look == '_' ) ) && n < MAX_IDENT_LEN ) { ident[n] = look; n++; look = getChar( ); @@ -934,7 +940,7 @@ static void assign_label( OperandInfo *operand_info, char *label ) } } -static OperandInfo *parseOperand( void ) +static OperandInfo *parseOperand( OpcodeInfo *opcode_info ) { OperandInfo *operand_info; @@ -962,6 +968,7 @@ static OperandInfo *parseOperand( void ) } else if( sym == S_string ) { operand_info->type = OPERAND_ABSOLUTE; operand_info->str = AllocateAndCopyStr( str ); + opcode_info->size = strlen( str ); sym = getSym( ); } else if( sym == S_lbrak ) { /* pointer indirection as [a] */ @@ -996,18 +1003,18 @@ static void parseOperands( OpcodeInfo *opcode_info ) OperandInfo *operand_info; while( sym != S_newline ) { - operand_info = parseOperand( ); + operand_info = parseOperand( opcode_info ); append_operand( opcode_info, operand_info ); nof_operands++; while( sym == S_comma ) { sym = getSym( ); - operand_info = parseOperand( ); + operand_info = parseOperand( opcode_info ); append_operand( opcode_info, operand_info ); nof_operands++; } } - if( nof_operands != opcode_info->nof_operands ) { + if( opcode_info->opcode != OPCODE_PSEUDO_DB && nof_operands != opcode_info->nof_operands ) { Abort( "'%s' expects %d operand(s), %d given", opcodename[opcode_info->opcode], opcode_info->nof_operands, nof_operands ); } @@ -1450,6 +1457,8 @@ static void generate_code( OpcodeInfo *opcode_info ) static void emit_opcode( OpcodeInfo *opcode_info ) { + OperandInfo *operand; + switch( opcode_info->opcode ) { case OPCODE_PSEUDO_ORG: break; @@ -1457,14 +1466,18 @@ static void emit_opcode( OpcodeInfo *opcode_info ) Emit_double_little_endian( opcode_info->operand->num ); break; case OPCODE_PSEUDO_DB: - if( opcode_info->operand->str == NULL ) { - Emit_byte( opcode_info->operand->num ); - } else { - int i; - int len = strlen( opcode_info->operand->str ); - for( i = 0; i < len; i++ ) { - Emit( "%c", opcode_info->operand->str[i] ); + operand = opcode_info->operand; + while( operand != NULL ) { + if( operand->str == NULL ) { + Emit_byte( operand->num ); + } else { + int i; + int len = strlen( operand->str ); + for( i = 0; i < len; i++ ) { + Emit( "%c", operand->str[i] ); + } } + operand = operand->next; } break; case OPCODE_HLT: diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c index 80bc815..87a3012 100644 --- a/ecomp-c/ec.c +++ b/ecomp-c/ec.c @@ -203,8 +203,14 @@ static int isDigit( int c ) static int isSpecial( int c ) { - if( c == '_' ) return 1; - return 0; + switch( c ) { + case '_': + case ' ': + return 1; + + default: + return 0; + } } static void skipWhite( void ) @@ -1733,6 +1739,9 @@ static void prologue( void ) static void reserve_initialize( Symbol *symbol ) { + int i; + int len; + switch( symbol->type->class ) { case SYMBOL_CLASS_SIMPLE_TYPE: if( symbol->type == integer_type ) { @@ -1751,28 +1760,33 @@ static void reserve_initialize( Symbol *symbol ) Emit( "\n" ); break; - case SYMBOL_CLASS_ARRAY_TYPE: { - int i = 0; - + case SYMBOL_CLASS_ARRAY_TYPE: if( symbol->type->type == character_type ) { - int len = strlen( symbol->string_value ); - Emit( "db \"" ); - while( i < len ) { - Emit( "%c", symbol->string_value[i] ); - i++; + i = 0; + Emit( "db " ); + if( symbol->string_value != NULL ) { + Emit( "\"" ); + len = strlen( symbol->string_value ); + while( i < len ) { + Emit( "%c", symbol->string_value[i] ); + i++; + } + Emit( "\"" ); } - Emit( "\"" ); while( i < symbol->type->dim ) { - Emit( "$00" ); + if( i > 0 ) { + Emit( ", " ); + } + Emit( "0" ); + i++; } Emit( "\n" ); } else { for( i = 0; i < symbol->type->dim; i++ ) { reserve_initialize( symbol->type ); } - } - - } break; + } + break; default: Abort( "Unhandled variable space reservation and initializiation for complex type '%s' in variable '%s'", diff --git a/ecomp-c/minie.ebnf b/ecomp-c/minie.ebnf index 6404899..c4d9513 100644 --- a/ecomp-c/minie.ebnf +++ b/ecomp-c/minie.ebnf @@ -1,10 +1,10 @@ Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" . Letter = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" . -Special = "_" . +Special = "_" | " " . Identifier = Letter { Letter | Digit | "_" } . Number = Digit { Digit } . -Character = "'" Digit | Letter | Special "'" . +Character = "'" Digit | Letter | Special | "'" . String = """" { Character } """" . Factor = Number | Character | String | Identifier | "(" Expression ")" | "not" Factor . diff --git a/ecomp-c/test.sh b/ecomp-c/test.sh index 94bed3b..a17d78e 100755 --- a/ecomp-c/test.sh +++ b/ecomp-c/test.sh @@ -16,6 +16,8 @@ variable_assign_from_type variable_assign_from_variable variable_assign_from_expression boolean_variable +character_variable +string_variable if_statement bool_conditions type_check_assignment diff --git a/ecomp-c/tests/asm-i386/mov.asm b/ecomp-c/tests/asm-i386/mov.asm index 7495e63..b823bf6 100644 --- a/ecomp-c/tests/asm-i386/mov.asm +++ b/ecomp-c/tests/asm-i386/mov.asm @@ -11,3 +11,4 @@ db "Hello" flag2: db $2 db "World" dd $01020304 +db "abc", 0, "def", 0 diff --git a/ecomp-c/tests/character_variable.e b/ecomp-c/tests/character_variable.e new file mode 100644 index 0000000..5dbd2d1 --- /dev/null +++ b/ecomp-c/tests/character_variable.e @@ -0,0 +1,15 @@ +/* + * define a character variable + */ + +module character_variable; + +const + C : character = 'A'; +var + c1 : character := C; + c2 : character := 'B'; + +begin + c2 := 'C'; +end diff --git a/ecomp-c/tests/character_variable.easm b/ecomp-c/tests/character_variable.easm new file mode 100644 index 0000000..ec0a50a --- /dev/null +++ b/ecomp-c/tests/character_variable.easm @@ -0,0 +1,14 @@ +format binary +use32 +org $1000000 +; CONST C -> character, 'A' +; DECL c1 -> character, 'A' +; DECL c2 -> character, 'B' +; LET c2 <- 'C' +mov eax, 67 +push eax +pop eax +mov [c2], al +hlt +c2: db $42 +c1: db $41 diff --git a/ecomp-c/tests/character_variable.easm_err b/ecomp-c/tests/character_variable.easm_err new file mode 100644 index 0000000..e69de29 diff --git a/ecomp-c/tests/character_variable.ecomp_err b/ecomp-c/tests/character_variable.ecomp_err new file mode 100644 index 0000000..e69de29 diff --git a/ecomp-c/tests/character_variable.erun b/ecomp-c/tests/character_variable.erun new file mode 100644 index 0000000..9c74e3b --- /dev/null +++ b/ecomp-c/tests/character_variable.erun @@ -0,0 +1,158 @@ +Read 15 bytes of code.. +1000000: B843000000 mov eax, 0x43 +1000005: 50 push eax +1000006: 58 pop eax +1000007: A20D000001 mov byte ptr [0x100000d], al +100000C: F4 hlt +100000D: 42 data +100000E: 41 data +core start 1000000 +data start 100000d +stack start 1800000 +Single step execution: +-- iteration 1 +1000000: B843000000 mov eax, 0x43 +EIP: 01000005 +ESP: 01800000 +EBP: 00000000 +EAX: 00000043 +EBX: 00000000 +ECX: 00000000 +EDX: 00000000 +ESI: 00000000 +EDI: 00000000 +stack: +data: +0100000D: 42410000 +01000011: 00000000 +01000015: 00000000 +01000019: 00000000 +0100001D: 00000000 +01000021: 00000000 +01000025: 00000000 +01000029: 00000000 +0100002D: 00000000 +01000031: 00000000 +01000035: 00000000 +01000039: 00000000 +0100003D: 00000000 +01000041: 00000000 +01000045: 00000000 +01000049: 00000000 +-- iteration 2 +1000005: 50 push eax +EIP: 01000006 +ESP: 017FFFFC +EBP: 00000000 +EAX: 00000043 +EBX: 00000000 +ECX: 00000000 +EDX: 00000000 +ESI: 00000000 +EDI: 00000000 +stack: +017FFFFC: 00000043 +data: +0100000D: 42410000 +01000011: 00000000 +01000015: 00000000 +01000019: 00000000 +0100001D: 00000000 +01000021: 00000000 +01000025: 00000000 +01000029: 00000000 +0100002D: 00000000 +01000031: 00000000 +01000035: 00000000 +01000039: 00000000 +0100003D: 00000000 +01000041: 00000000 +01000045: 00000000 +01000049: 00000000 +-- iteration 3 +1000006: 58 pop eax +EIP: 01000007 +ESP: 01800000 +EBP: 00000000 +EAX: 00000043 +EBX: 00000000 +ECX: 00000000 +EDX: 00000000 +ESI: 00000000 +EDI: 00000000 +stack: +data: +0100000D: 42410000 +01000011: 00000000 +01000015: 00000000 +01000019: 00000000 +0100001D: 00000000 +01000021: 00000000 +01000025: 00000000 +01000029: 00000000 +0100002D: 00000000 +01000031: 00000000 +01000035: 00000000 +01000039: 00000000 +0100003D: 00000000 +01000041: 00000000 +01000045: 00000000 +01000049: 00000000 +-- iteration 4 +1000007: A20D000001 mov byte ptr [0x100000d], al +EIP: 0100000C +ESP: 01800000 +EBP: 00000000 +EAX: 00000043 +EBX: 00000000 +ECX: 00000000 +EDX: 00000000 +ESI: 00000000 +EDI: 00000000 +stack: +data: +0100000D: 43410000 +01000011: 00000000 +01000015: 00000000 +01000019: 00000000 +0100001D: 00000000 +01000021: 00000000 +01000025: 00000000 +01000029: 00000000 +0100002D: 00000000 +01000031: 00000000 +01000035: 00000000 +01000039: 00000000 +0100003D: 00000000 +01000041: 00000000 +01000045: 00000000 +01000049: 00000000 +-- iteration 5 +100000C: F4 hlt +EIP: 0100000D +ESP: 01800000 +EBP: 00000000 +EAX: 00000043 +EBX: 00000000 +ECX: 00000000 +EDX: 00000000 +ESI: 00000000 +EDI: 00000000 +stack: +data: +0100000D: 43410000 +01000011: 00000000 +01000015: 00000000 +01000019: 00000000 +0100001D: 00000000 +01000021: 00000000 +01000025: 00000000 +01000029: 00000000 +0100002D: 00000000 +01000031: 00000000 +01000035: 00000000 +01000039: 00000000 +0100003D: 00000000 +01000041: 00000000 +01000045: 00000000 +01000049: 00000000 diff --git a/ecomp-c/tests/string_variable.e b/ecomp-c/tests/string_variable.e new file mode 100644 index 0000000..e6cf1c4 --- /dev/null +++ b/ecomp-c/tests/string_variable.e @@ -0,0 +1,16 @@ +/* + * define a string variable + */ + +module string_variable; + +const + S : array 11 of character = "hello world"; + +var + s1 : array 11 of character := S; + s2 : array 17 of character := "hello again world"; + s3 : array 12 of character; + +begin +end diff --git a/ecomp-c/tests/string_variable.easm b/ecomp-c/tests/string_variable.easm new file mode 100644 index 0000000..48b3639 --- /dev/null +++ b/ecomp-c/tests/string_variable.easm @@ -0,0 +1,11 @@ +format binary +use32 +org $1000000 +; CONST S -> array 11 of character, array 11 of character = { ... } +; DECL s1 -> array 11 of character, array 11 of character = { ... } +; DECL s2 -> array 17 of character, array 17 of character = { ... } +; DECL s3 -> array 12 of character, array 12 of character = { ... } +hlt +s3: db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +s2: db "hello again world" +s1: db "hello world" diff --git a/ecomp-c/tests/string_variable.easm_err b/ecomp-c/tests/string_variable.easm_err new file mode 100644 index 0000000..e69de29 diff --git a/ecomp-c/tests/string_variable.ecomp_err b/ecomp-c/tests/string_variable.ecomp_err new file mode 100644 index 0000000..e69de29 diff --git a/ecomp-c/tests/string_variable.erun b/ecomp-c/tests/string_variable.erun new file mode 100644 index 0000000..1cfc309 --- /dev/null +++ b/ecomp-c/tests/string_variable.erun @@ -0,0 +1,48 @@ +Read 41 bytes of code.. +1000000: F4 hlt +1000001: 0000 data +1000003: 0000 data +1000005: 0000 data +1000007: 0000 data +1000009: 0000 data +100000B: 0000 data +100000D: 68656C6C6F data +1000012: 206167 data +1000015: 61 data +1000016: 696E20776F726C data +100001D: 6468656C6C6F data +1000023: 20776F data +1000026: 726C data +core start 1000000 +data start 1000001 +stack start 1800000 +Single step execution: +-- iteration 1 +1000000: F4 hlt +EIP: 01000001 +ESP: 01800000 +EBP: 00000000 +EAX: 00000000 +EBX: 00000000 +ECX: 00000000 +EDX: 00000000 +ESI: 00000000 +EDI: 00000000 +stack: +data: +01000001: 00000000 +01000005: 00000000 +01000009: 00000000 +0100000D: 68656C6C +01000011: 6F206167 +01000015: 61696E20 +01000019: 776F726C +0100001D: 6468656C +01000021: 6C6F2077 +01000025: 6F726C64 +01000029: 00000000 +0100002D: 00000000 +01000031: 00000000 +01000035: 00000000 +01000039: 00000000 +0100003D: 00000000 -- cgit v1.2.3-54-g00ecf