From e24b68028c96c7d650243602f17b3f4e04d1f40d Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 9 Sep 2026 19:09:06 -0400 Subject: [PATCH] drafting an asm parser (rudimentary) --- code/8086/info.h | 9 + code/8086/parser.c | 302 ++++++++++++++++++++++++++++++++++ code/8086/parser.h | 20 +++ code/8086/serializer.c | 139 +--------------- code/8086/serializer_tables.h | 142 ++++++++++++++++ code/duffle/text.h | 1 + code/part_1/sim_8086.c | 1 + 7 files changed, 476 insertions(+), 138 deletions(-) create mode 100644 code/8086/parser.c create mode 100644 code/8086/parser.h create mode 100644 code/8086/serializer_tables.h diff --git a/code/8086/info.h b/code/8086/info.h index 6f9694b..71ce1c3 100644 --- a/code/8086/info.h +++ b/code/8086/info.h @@ -31,6 +31,11 @@ typedef Enum_(U1, X8616_InfoCode) { x8616_info_serialize_unsupported_form = 0x0D, x8616_info_serialize_output_full = 0x0E, + x8616_info_parse_bad_request = 0x0F, + x8616_info_parse_syntax = 0x10, + x8616_info_parse_unknown_mnemonic = 0x11, + x8616_info_parse_output_full = 0x12, + x8616_info_count, }; @@ -65,6 +70,10 @@ RO_ global Str8 x8616_info_templates[x8616_info_count] = { [x8616_info_serialize_invalid_record] = slit8("Serialize record is not printable (op )."), [x8616_info_serialize_unsupported_form] = slit8("Serialize record has an unsupported display form (op )."), [x8616_info_serialize_output_full] = slit8("Serialize output is full at record : capacity , produced ."), + [x8616_info_parse_bad_request] = slit8("Parse request is missing source, output, or info arena."), + [x8616_info_parse_syntax] = slit8("Parse syntax error at ."), + [x8616_info_parse_unknown_mnemonic] = slit8("Unknown mnemonic at ."), + [x8616_info_parse_output_full] = slit8("Parse output is full: capacity , produced ."), }; typedef Struct_(X8616_InfoList) { diff --git a/code/8086/parser.c b/code/8086/parser.c new file mode 100644 index 0000000..4c139a2 --- /dev/null +++ b/code/8086/parser.c @@ -0,0 +1,302 @@ +#ifdef INTELLISENSE_DIRECTIVES +# include "parser.h" +# include "serializer_tables.h" +#endif + +FI_ void x8616_parse_skip_ws(Str8_R cur) { + while (cur->len && char_is_space(cur->ptr[0])) { cur->ptr += 1; cur->len -= 1; } +} + +FI_ B4 x8616_parse_eat(Str8_R cur, Str8 lit) { + B4 too_big = cur->len < lit.len; + B4 miss = too_big || mem_match(u8_(cur->ptr), u8_(lit.ptr), lit.len) == 0; + if (miss) return 0; + cur->ptr += lit.len; + cur->len -= lit.len; + return 1; +} + +FI_ U4 x8616_parse_lookup(Str8_R cur, Str8* table, U4 table_len) { + U4 best = table_len; + U8 best_len = 0; + for (U4 i = 0; i < table_len; ++i) + { + Str8 lit = table[i]; + B4 empty = lit.len == 0; + B4 too_big = lit.len > cur->len; + B4 worse = lit.len <= best_len; + B4 skip = empty || too_big || worse; + B4 miss = skip || mem_match(u8_(cur->ptr), u8_(lit.ptr), lit.len) == 0; + if (miss) continue; + best = i; + best_len = lit.len; + } + if (best < table_len) { + cur->ptr += best_len; + cur->len -= best_len; + } + return best; +} + +FI_ B4 x8616_parse_number(Str8_R cur, U2_R value, B4_R neg_out) { + x8616_parse_skip_ws(cur); + B4 neg = 0; + if (x8616_parse_eat(cur, slit8("-"))) neg = 1; + if (cur->len == 0 || char_is_digit(cur->ptr[0], 10) == 0) return 0; + U8 start = 0; + while (start < cur->len && char_is_digit(cur->ptr[start], 10)) start += 1; + U8 mag = u8_from_str8(str8(cur->ptr, start), 10); + cur->ptr += start; + cur->len -= start; + value[0] = u2_(mag); + neg_out[0] = neg; + return 1; +} + +internal B4 x8616_parse_memory(Str8_R cur, X8616_DecodedOperand_R op) +{ + B4 ok = 1; + if (x8616_parse_eat(cur, slit8("[")) == 0) { ok = 0; goto exit; } + x8616_parse_skip_ws(cur); + + U4 ea_n = Array_len(x8616_serialize_ea); + U4 ea = x8616_parse_lookup(cur, x8616_serialize_ea, ea_n); + if (ea < ea_n) + { + op->flags = x8616_decoded_operand_memory; + op->ea = C_(X8616_EA, ea); + x8616_parse_skip_ws(cur); + if (x8616_parse_eat(cur, slit8("+"))) { + U2 mag = 0; B4 neg = 0; + x8616_parse_skip_ws(cur); + if (x8616_parse_number(cur, & mag, & neg) == 0) { ok = 0; goto exit; } + op->displacement = neg ? s2_(-s4_(mag)) : s2_(mag); + op->displacement_bytes = (u2_(op->displacement) > 0x7F && op->displacement >= 0) || op->displacement < -128 ? 2 : (op->displacement ? 1 : 0); + } + else if (x8616_parse_eat(cur, slit8("-"))) { + U2 mag = 0; B4 dummy = 0; + x8616_parse_skip_ws(cur); + if (x8616_parse_number(cur, & mag, & dummy) == 0) { ok = 0; goto exit; } + op->displacement = s2_(-s4_(mag)); + op->displacement_bytes = op->displacement < -128 ? 2 : 1; + } + } + else { + U2 mag = 0; B4 neg = 0; + if (x8616_parse_number(cur, & mag, & neg) == 0) { ok = 0; goto exit; } + op->flags = x8616_decoded_operand_memory | x8616_decoded_operand_direct; + op->address = mag; + op->ea = x8616_ea_direct; + } + x8616_parse_skip_ws(cur); + if (x8616_parse_eat(cur, slit8("]")) == 0) { ok = 0; goto exit; } +exit: + return ok; +} + +internal B4 +x8616_parse_operand(Str8_R cur, X8616_DecodedInstruction_R inst, X8616_DecodedOperand_R op) +{ + B4 ok = 1; + x8616_parse_skip_ws(cur); + X8616_WidthMode size = x8616_width_dynamic; + if (x8616_parse_eat(cur, slit8("byte "))) size = x8616_width_byte; + else if (x8616_parse_eat(cur, slit8("word "))) size = x8616_width_word; + if (x8616_parse_eat(cur, slit8("far "))) inst->flags |= x8616_encoding_far; + x8616_parse_skip_ws(cur); + + U4 seg_n = Array_len(x8616_serialize_seg); + Str8 save = cur[0]; + U4 seg = x8616_parse_lookup(cur, x8616_serialize_seg, seg_n); + if (seg < seg_n) + { + x8616_parse_skip_ws(cur); + if (x8616_parse_eat(cur, slit8(":"))) { + inst->prefixes.has_segment = 1; + inst->prefixes.segment = C_(X8616_Segment, seg); + x8616_parse_skip_ws(cur); + if (x8616_parse_memory(cur, op) == 0) { ok = 0; goto exit; } + } + else { + op->flags = x8616_decoded_operand_segment; + op->segment = C_(X8616_Segment, seg); + op->width = x8616_width_word; + } + } + else + { + cur[0] = save; + U4 r16_n = Array_len(x8616_serialize_reg16); + U4 r8_n = Array_len(x8616_serialize_reg8); + U4 r16 = x8616_parse_lookup(cur, x8616_serialize_reg16, r16_n); + if (r16 < r16_n) { + op->flags = x8616_decoded_operand_register; + op->width = x8616_width_word; + op->reg.r16 = C_(X8616_Reg16, r16); + } + else + { + cur[0] = save; + U4 r8 = x8616_parse_lookup(cur, x8616_serialize_reg8, r8_n); + if (r8 < r8_n) { + op->flags = x8616_decoded_operand_register; + op->width = x8616_width_byte; + op->reg.r8 = C_(X8616_Reg8, r8); + } + else if (x8616_parse_eat(cur, slit8("$"))) { + B4 neg = 0; + if (x8616_parse_eat(cur, slit8("+"))) {} + else if (x8616_parse_eat(cur, slit8("-"))) neg = 1; + else { ok = 0; goto exit; } + U2 mag = 0; B4 extra = 0; + if (x8616_parse_number(cur, & mag, & extra) == 0) { ok = 0; goto exit; } + if (extra) neg = 1; + op->flags = x8616_decoded_operand_relative; + op->displacement = neg ? s2_(-s4_(mag)) : s2_(mag); + op->width = x8616_width_byte; + } + else if (cur->len && cur->ptr[0] == '[') { + if (x8616_parse_memory(cur, op) == 0) { ok = 0; goto exit; } + } + else + { + U2 mag = 0; B4 neg = 0; + Str8 before = *cur; + if (x8616_parse_number(cur, & mag, & neg) == 0) { ok = 0; goto exit; } + x8616_parse_skip_ws(cur); + if (x8616_parse_eat(cur, slit8(":"))) { + U2 off = 0; B4 off_neg = 0; + if (x8616_parse_number(cur, & off, & off_neg) == 0) { ok = 0; goto exit; } + op->flags = x8616_decoded_operand_far_ptr; + op->far_segment = mag; + op->far_offset = off; + } + else { + *cur = before; + if (x8616_parse_number(cur, & mag, & neg) == 0) { ok = 0; goto exit; } + op->flags = x8616_decoded_operand_immediate; + op->immediate = mag; + if (neg) { + op->flags |= x8616_decoded_operand_sign_extended; + op->immediate = u2_(s2_(-s4_(mag))); + } + op->immediate_bytes = mag > 0xFF ? 2 : 1; + op->width = mag > 0xFF ? x8616_width_word : x8616_width_byte; + } + } + } + } + + if (size != x8616_width_dynamic) { + op->width = size; + if (inst->width == x8616_width_dynamic) inst->width = size; + } +exit: + return ok; +} + +internal B4 x8616_parse_line(Str8 line, X8616_DecodedInstruction_R inst) +{ + B4 ok = 1; + x8616_parse_skip_ws(& line); + if (line.len == 0) { ok = 0; goto exit; } + + if (x8616_parse_eat(& line, slit8("lock "))) inst->prefixes.lock = 1; + if (x8616_parse_eat(& line, slit8("repne "))) { + inst->prefixes.has_repeat = 1; + inst->prefixes.repeat = x8616_repne; + } + else if (x8616_parse_eat(& line, slit8("rep "))) { + inst->prefixes.has_repeat = 1; + inst->prefixes.repeat = x8616_rep; + } + + U4 mnem_n = Array_len(x8616_serialize_mnemonic); + U4 mnem = x8616_parse_lookup(& line, x8616_serialize_mnemonic, mnem_n); + if (mnem >= mnem_n) { ok = 0; goto exit; } + inst->op = C_(X8616_Op, mnem); + + if (inst->op == x8616_op_movs || inst->op == x8616_op_cmps || inst->op == x8616_op_scas + || inst->op == x8616_op_lods || inst->op == x8616_op_stos) { + if (x8616_parse_eat(& line, slit8("b"))) inst->width = x8616_width_byte; + else if (x8616_parse_eat(& line, slit8("w"))) inst->width = x8616_width_word; + } + + x8616_parse_skip_ws(& line); + if (line.len == 0) goto exit; + + if (x8616_parse_operand(& line, inst, inst->operands + 0) == 0) { ok = 0; goto exit; } + inst->operand_count = 1; + x8616_parse_skip_ws(& line); + if (x8616_parse_eat(& line, slit8(","))) { + if (x8616_parse_operand(& line, inst, inst->operands + 1) == 0) { ok = 0; goto exit; } + inst->operand_count = 2; + } + x8616_parse_skip_ws(& line); + if (inst->width == x8616_width_dynamic) { + if (inst->operand_count && inst->operands[0].width != x8616_width_dynamic) + inst->width = inst->operands[0].width; + } + ok = line.len == 0; +exit: + return ok; +} + +X8616_ParseInfo x8616_parse_instructions(X8616_ParseRequest request) +{ + X8616_ParseInfo result = {0}; + X8616_InfoList local = {0}; + X8616_InfoList_R msgs = request.msgs ? request.msgs : & local; + U4 offset = 0; + + B4 bad = request.source.ptr == 0 && request.source.len != 0; + bad |= request.instruction_cap && request.out_instructions == 0; + bad |= request.info_arena == 0; + if (bad) { + if (request.info_arena) { + x8616_info_push(request.info_arena, msgs, x8616_info_error + , x8616_info_parse_bad_request, 0, 0, 0, 0); + } + goto exit; + } + + Str8 cur = request.source; + if (x8616_parse_eat(& cur, x8616_serialize_header)) {} + + offset = u4_(request.source.len - cur.len); + while (cur.len) + { + U8 n = 0; + while (n < cur.len && cur.ptr[n] != '\n') n += 1; + Str8 line = str8(cur.ptr, n); + U8 step = n + (n < cur.len); + U4 line_at = offset; + cur.ptr += step; + cur.len -= step; + offset += u4_(step); + + while (line.len && char_is_space(line.ptr[line.len - 1])) line.len -= 1; + x8616_parse_skip_ws(& line); + if (line.len == 0) continue; + + if (result.instruction_count == request.instruction_cap) { + x8616_info_push(request.info_arena, msgs, x8616_info_error + , x8616_info_parse_output_full, line_at, 0, request.instruction_cap, result.instruction_count); + goto exit; + } + + X8616_DecodedInstruction inst = {0}; + if (x8616_parse_line(line, & inst) == 0) { + x8616_info_push(request.info_arena, msgs, x8616_info_error + , x8616_info_parse_syntax, line_at, u2_(line.len), 0, 0); + continue; + } + request.out_instructions[result.instruction_count] = inst; + result.instruction_count += 1; + } + +exit: + result.source_consumed = offset; + result.msgs = *msgs; + return result; +} diff --git a/code/8086/parser.h b/code/8086/parser.h new file mode 100644 index 0000000..f49f472 --- /dev/null +++ b/code/8086/parser.h @@ -0,0 +1,20 @@ +#ifdef INTELLISENSE_DIRECTIVES +# pragma once +# include "decoder.h" +#endif + +typedef Struct_(X8616_ParseRequest) { + Str8 source; + X8616_DecodedInstruction* out_instructions; + U4 instruction_cap; + FArena* info_arena; + X8616_InfoList_R msgs; +}; + +typedef Struct_(X8616_ParseInfo) { + X8616_InfoList msgs; + U4 instruction_count; + U4 source_consumed; +}; + +X8616_ParseInfo x8616_parse_instructions(X8616_ParseRequest request); diff --git a/code/8086/serializer.c b/code/8086/serializer.c index d7f27a1..67b6c8e 100644 --- a/code/8086/serializer.c +++ b/code/8086/serializer.c @@ -1,145 +1,8 @@ #ifdef INTELLISENSE_DIRECTIVES # include "serializer.h" +# include "serializer_tables.h" #endif -RO_ global Str8 x8616_serialize_header = slit8("bits 16\n\n"); - -RO_ global Str8 x8616_serialize_mnemonic[] = { - [x8616_op_invalid] = slit8(""), - [x8616_op_nop] = slit8("nop"), - [x8616_op_mov] = slit8("mov"), - [x8616_op_add] = slit8("add"), - [x8616_op_or] = slit8("or"), - [x8616_op_adc] = slit8("adc"), - [x8616_op_sbb] = slit8("sbb"), - [x8616_op_and] = slit8("and"), - [x8616_op_sub] = slit8("sub"), - [x8616_op_xor] = slit8("xor"), - [x8616_op_cmp] = slit8("cmp"), - [x8616_op_push] = slit8("push"), - [x8616_op_pop] = slit8("pop"), - [x8616_op_xchg] = slit8("xchg"), - [x8616_op_in] = slit8("in"), - [x8616_op_out] = slit8("out"), - [x8616_op_xlat] = slit8("xlat"), - [x8616_op_lea] = slit8("lea"), - [x8616_op_lds] = slit8("lds"), - [x8616_op_les] = slit8("les"), - [x8616_op_lahf] = slit8("lahf"), - [x8616_op_sahf] = slit8("sahf"), - [x8616_op_pushf] = slit8("pushf"), - [x8616_op_popf] = slit8("popf"), - [x8616_op_inc] = slit8("inc"), - [x8616_op_aaa] = slit8("aaa"), - [x8616_op_daa] = slit8("daa"), - [x8616_op_dec] = slit8("dec"), - [x8616_op_neg] = slit8("neg"), - [x8616_op_aas] = slit8("aas"), - [x8616_op_das] = slit8("das"), - [x8616_op_mul] = slit8("mul"), - [x8616_op_imul] = slit8("imul"), - [x8616_op_aam] = slit8("aam"), - [x8616_op_div] = slit8("div"), - [x8616_op_idiv] = slit8("idiv"), - [x8616_op_aad] = slit8("aad"), - [x8616_op_cbw] = slit8("cbw"), - [x8616_op_cwd] = slit8("cwd"), - [x8616_op_not] = slit8("not"), - [x8616_op_shl] = slit8("shl"), - [x8616_op_shr] = slit8("shr"), - [x8616_op_sar] = slit8("sar"), - [x8616_op_rol] = slit8("rol"), - [x8616_op_ror] = slit8("ror"), - [x8616_op_rcl] = slit8("rcl"), - [x8616_op_rcr] = slit8("rcr"), - [x8616_op_test] = slit8("test"), - [x8616_op_rep] = slit8(""), - [x8616_op_movs] = slit8("movs"), - [x8616_op_cmps] = slit8("cmps"), - [x8616_op_scas] = slit8("scas"), - [x8616_op_lods] = slit8("lods"), - [x8616_op_stos] = slit8("stos"), - [x8616_op_call] = slit8("call"), - [x8616_op_jmp] = slit8("jmp"), - [x8616_op_ret] = slit8("ret"), - [x8616_op_retf] = slit8("retf"), - [x8616_op_je] = slit8("je"), - [x8616_op_jl] = slit8("jl"), - [x8616_op_jle] = slit8("jle"), - [x8616_op_jb] = slit8("jb"), - [x8616_op_jbe] = slit8("jbe"), - [x8616_op_jp] = slit8("jp"), - [x8616_op_jo] = slit8("jo"), - [x8616_op_js] = slit8("js"), - [x8616_op_jne] = slit8("jne"), - [x8616_op_jnl] = slit8("jnl"), - [x8616_op_jg] = slit8("jg"), - [x8616_op_jnb] = slit8("jnb"), - [x8616_op_ja] = slit8("ja"), - [x8616_op_jnp] = slit8("jnp"), - [x8616_op_jno] = slit8("jno"), - [x8616_op_jns] = slit8("jns"), - [x8616_op_loop] = slit8("loop"), - [x8616_op_loopz] = slit8("loopz"), - [x8616_op_loopnz] = slit8("loopnz"), - [x8616_op_jcxz] = slit8("jcxz"), - [x8616_op_int] = slit8("int"), - [x8616_op_int3] = slit8("int3"), - [x8616_op_into] = slit8("into"), - [x8616_op_iret] = slit8("iret"), - [x8616_op_clc] = slit8("clc"), - [x8616_op_cmc] = slit8("cmc"), - [x8616_op_stc] = slit8("stc"), - [x8616_op_cld] = slit8("cld"), - [x8616_op_std] = slit8("std"), - [x8616_op_cli] = slit8("cli"), - [x8616_op_sti] = slit8("sti"), - [x8616_op_hlt] = slit8("hlt"), - [x8616_op_wait] = slit8("wait"), - [x8616_op_lock] = slit8(""), - [x8616_op_segment] = slit8(""), -}; - -RO_ global Str8 x8616_serialize_reg8[] = { - [x8616_al] = slit8("al"), - [x8616_cl] = slit8("cl"), - [x8616_dl] = slit8("dl"), - [x8616_bl] = slit8("bl"), - [x8616_ah] = slit8("ah"), - [x8616_ch] = slit8("ch"), - [x8616_dh] = slit8("dh"), - [x8616_bh] = slit8("bh"), -}; - -RO_ global Str8 x8616_serialize_reg16[] = { - [x8616_ax] = slit8("ax"), - [x8616_cx] = slit8("cx"), - [x8616_dx] = slit8("dx"), - [x8616_bx] = slit8("bx"), - [x8616_sp] = slit8("sp"), - [x8616_bp] = slit8("bp"), - [x8616_si] = slit8("si"), - [x8616_di] = slit8("di"), -}; - -RO_ global Str8 x8616_serialize_seg[] = { - [x8616_es] = slit8("es"), - [x8616_cs] = slit8("cs"), - [x8616_ss] = slit8("ss"), - [x8616_ds] = slit8("ds"), -}; - -RO_ global Str8 x8616_serialize_ea[] = { - [x8616_ea_bx_si] = slit8("bx + si"), - [x8616_ea_bx_di] = slit8("bx + di"), - [x8616_ea_bp_si] = slit8("bp + si"), - [x8616_ea_bp_di] = slit8("bp + di"), - [x8616_ea_si] = slit8("si"), - [x8616_ea_di] = slit8("di"), - [x8616_ea_bp] = slit8("bp"), - [x8616_ea_bx] = slit8("bx"), -}; - typedef Enum_(U1, X8616_SerializeSizeWhere) { x8616_serialize_size_none = 0x00, x8616_serialize_size_before_mem = 0x01, diff --git a/code/8086/serializer_tables.h b/code/8086/serializer_tables.h new file mode 100644 index 0000000..d25cfac --- /dev/null +++ b/code/8086/serializer_tables.h @@ -0,0 +1,142 @@ +#ifdef INTELLISENSE_DIRECTIVES +# pragma once +# include "encoder.h" +#endif + +RO_ global Str8 x8616_serialize_header = slit8("bits 16\n\n"); + +RO_ global Str8 x8616_serialize_mnemonic[] = { + [x8616_op_invalid] = slit8(""), + [x8616_op_nop] = slit8("nop"), + [x8616_op_mov] = slit8("mov"), + [x8616_op_add] = slit8("add"), + [x8616_op_or] = slit8("or"), + [x8616_op_adc] = slit8("adc"), + [x8616_op_sbb] = slit8("sbb"), + [x8616_op_and] = slit8("and"), + [x8616_op_sub] = slit8("sub"), + [x8616_op_xor] = slit8("xor"), + [x8616_op_cmp] = slit8("cmp"), + [x8616_op_push] = slit8("push"), + [x8616_op_pop] = slit8("pop"), + [x8616_op_xchg] = slit8("xchg"), + [x8616_op_in] = slit8("in"), + [x8616_op_out] = slit8("out"), + [x8616_op_xlat] = slit8("xlat"), + [x8616_op_lea] = slit8("lea"), + [x8616_op_lds] = slit8("lds"), + [x8616_op_les] = slit8("les"), + [x8616_op_lahf] = slit8("lahf"), + [x8616_op_sahf] = slit8("sahf"), + [x8616_op_pushf] = slit8("pushf"), + [x8616_op_popf] = slit8("popf"), + [x8616_op_inc] = slit8("inc"), + [x8616_op_aaa] = slit8("aaa"), + [x8616_op_daa] = slit8("daa"), + [x8616_op_dec] = slit8("dec"), + [x8616_op_neg] = slit8("neg"), + [x8616_op_aas] = slit8("aas"), + [x8616_op_das] = slit8("das"), + [x8616_op_mul] = slit8("mul"), + [x8616_op_imul] = slit8("imul"), + [x8616_op_aam] = slit8("aam"), + [x8616_op_div] = slit8("div"), + [x8616_op_idiv] = slit8("idiv"), + [x8616_op_aad] = slit8("aad"), + [x8616_op_cbw] = slit8("cbw"), + [x8616_op_cwd] = slit8("cwd"), + [x8616_op_not] = slit8("not"), + [x8616_op_shl] = slit8("shl"), + [x8616_op_shr] = slit8("shr"), + [x8616_op_sar] = slit8("sar"), + [x8616_op_rol] = slit8("rol"), + [x8616_op_ror] = slit8("ror"), + [x8616_op_rcl] = slit8("rcl"), + [x8616_op_rcr] = slit8("rcr"), + [x8616_op_test] = slit8("test"), + [x8616_op_rep] = slit8(""), + [x8616_op_movs] = slit8("movs"), + [x8616_op_cmps] = slit8("cmps"), + [x8616_op_scas] = slit8("scas"), + [x8616_op_lods] = slit8("lods"), + [x8616_op_stos] = slit8("stos"), + [x8616_op_call] = slit8("call"), + [x8616_op_jmp] = slit8("jmp"), + [x8616_op_ret] = slit8("ret"), + [x8616_op_retf] = slit8("retf"), + [x8616_op_je] = slit8("je"), + [x8616_op_jl] = slit8("jl"), + [x8616_op_jle] = slit8("jle"), + [x8616_op_jb] = slit8("jb"), + [x8616_op_jbe] = slit8("jbe"), + [x8616_op_jp] = slit8("jp"), + [x8616_op_jo] = slit8("jo"), + [x8616_op_js] = slit8("js"), + [x8616_op_jne] = slit8("jne"), + [x8616_op_jnl] = slit8("jnl"), + [x8616_op_jg] = slit8("jg"), + [x8616_op_jnb] = slit8("jnb"), + [x8616_op_ja] = slit8("ja"), + [x8616_op_jnp] = slit8("jnp"), + [x8616_op_jno] = slit8("jno"), + [x8616_op_jns] = slit8("jns"), + [x8616_op_loop] = slit8("loop"), + [x8616_op_loopz] = slit8("loopz"), + [x8616_op_loopnz] = slit8("loopnz"), + [x8616_op_jcxz] = slit8("jcxz"), + [x8616_op_int] = slit8("int"), + [x8616_op_int3] = slit8("int3"), + [x8616_op_into] = slit8("into"), + [x8616_op_iret] = slit8("iret"), + [x8616_op_clc] = slit8("clc"), + [x8616_op_cmc] = slit8("cmc"), + [x8616_op_stc] = slit8("stc"), + [x8616_op_cld] = slit8("cld"), + [x8616_op_std] = slit8("std"), + [x8616_op_cli] = slit8("cli"), + [x8616_op_sti] = slit8("sti"), + [x8616_op_hlt] = slit8("hlt"), + [x8616_op_wait] = slit8("wait"), + [x8616_op_lock] = slit8(""), + [x8616_op_segment] = slit8(""), +}; + +RO_ global Str8 x8616_serialize_reg8[] = { + [x8616_al] = slit8("al"), + [x8616_cl] = slit8("cl"), + [x8616_dl] = slit8("dl"), + [x8616_bl] = slit8("bl"), + [x8616_ah] = slit8("ah"), + [x8616_ch] = slit8("ch"), + [x8616_dh] = slit8("dh"), + [x8616_bh] = slit8("bh"), +}; + +RO_ global Str8 x8616_serialize_reg16[] = { + [x8616_ax] = slit8("ax"), + [x8616_cx] = slit8("cx"), + [x8616_dx] = slit8("dx"), + [x8616_bx] = slit8("bx"), + [x8616_sp] = slit8("sp"), + [x8616_bp] = slit8("bp"), + [x8616_si] = slit8("si"), + [x8616_di] = slit8("di"), +}; + +RO_ global Str8 x8616_serialize_seg[] = { + [x8616_es] = slit8("es"), + [x8616_cs] = slit8("cs"), + [x8616_ss] = slit8("ss"), + [x8616_ds] = slit8("ds"), +}; + +RO_ global Str8 x8616_serialize_ea[] = { + [x8616_ea_bx_si] = slit8("bx + si"), + [x8616_ea_bx_di] = slit8("bx + di"), + [x8616_ea_bp_si] = slit8("bp + si"), + [x8616_ea_bp_di] = slit8("bp + di"), + [x8616_ea_si] = slit8("si"), + [x8616_ea_di] = slit8("di"), + [x8616_ea_bp] = slit8("bp"), + [x8616_ea_bx] = slit8("bx"), +}; diff --git a/code/duffle/text.h b/code/duffle/text.h index 9806bcf..de67622 100644 --- a/code/duffle/text.h +++ b/code/duffle/text.h @@ -21,6 +21,7 @@ RO_ U8 integer_symbol_reverse[128] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, }; +FI_ B4 char_is_space(UTF8 c) { return(c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\v'); } FI_ B4 char_is_upper(UTF8 c) { return('A' <= c && c <= 'Z'); } FI_ UTF8 char_to_lower(UTF8 c) { if (char_is_upper(c)) { c += ('a' - 'A'); } return(c); } FI_ B4 char_is_digit(UTF8 c, U4 base) { diff --git a/code/part_1/sim_8086.c b/code/part_1/sim_8086.c index ed844aa..475c908 100644 --- a/code/part_1/sim_8086.c +++ b/code/part_1/sim_8086.c @@ -17,6 +17,7 @@ #include "8086/info_render.h" #include "8086/decoder.h" #include "8086/serializer.h" +#include "8086/serializer_tables.h" #include "8086/gen/decoder_table.h" #include "8086/decoder.c"