From ea6edf6efef538e60fe02edeee6f5f4bea4868a7 Mon Sep 17 00:00:00 2001 From: jmug Date: Sun, 2 Feb 2025 00:09:58 -0800 Subject: [PATCH] Assembler finished. Signed-off-by: jmug --- hw2/bin/simulator.ml | 112 ++++++++++++++++++++++++++++++++++++++-- hw2/test/gradedtests.ml | 2 +- 2 files changed, 110 insertions(+), 4 deletions(-) diff --git a/hw2/bin/simulator.ml b/hw2/bin/simulator.ml index 53d419a..7d5d06d 100644 --- a/hw2/bin/simulator.ml +++ b/hw2/bin/simulator.ml @@ -406,9 +406,115 @@ exception Redefined_sym of lbl HINT: List.fold_left and List.fold_right are your friends. *) -let is_size (is : ins list) : quad = failwith "is_size not implemented" -let ds_size (ds : data list) : quad = failwith "ds_size not implemented" -let assemble (p : prog) : exec = failwith "assemble unimplemented" + +exception UnexpectedData +exception UnexpectedText + +let is_size (is : ins list) : quad = 8L *. (Int64.of_int @@ List.length is) +;; + +let elem_is_size (e : elem) : quad = match e with +| { asm = Text il; _ } -> is_size il +| _ -> raise UnexpectedData +;; + +let ds_size (ds : data list) : quad = + let d_size d acc = match d with + | Asciz s -> acc +. 1L +. (Int64.of_int @@ String.length s) + | Quad _ -> acc +. 8L + in + List.fold_right d_size ds 0L +;; + +let elem_ds_size (e : elem) : quad = match e with +| { asm = Data dl; _ } -> ds_size dl +| _ -> raise UnexpectedText +;; + +let elem_size (e : elem) : quad = match e with +| { asm = Data dl; _ } -> ds_size dl +| { asm = Text il; _ } -> is_size il +;; + +type symbol_table = (lbl * quad) list + +let build_symbol_table (p : prog) : symbol_table = + let accum_elem ((addr, tbl) as acc) ({ lbl = l; _ } as e) = + let curr = List.assoc_opt l tbl in + let new_addr = addr +. (elem_size e) in + let new_sym_tbl = (l, addr) :: tbl in + match curr with + | Some _ -> raise (Redefined_sym l) + | None -> (new_addr, new_sym_tbl) + in + let (_, sym_tbl) = List.fold_left accum_elem (mem_bot, []) p in + sym_tbl +;; + +let patch_imm (i : imm) (t : symbol_table) : imm = match i with +| Lbl l -> + let addr_opt = List.assoc_opt l t in + (match addr_opt with + | Some addr -> Lit addr + | None -> raise (Undefined_sym l)) +| _ -> i +;; + +let patch_data (t : symbol_table) (d : data) : data = match d with + | Quad i -> Quad (patch_imm i t) + | _ -> d +;; + +let patch_ins (t : symbol_table) ((op, operands) as i : ins) : ins = + let patch_operand o = match o with + | Imm im -> Imm (patch_imm im t) + | Ind1 im -> Ind1 (patch_imm im t) + | Ind3 (im, r) -> Ind3 (patch_imm im t, r) + | _ -> o + in + let new_operands = List.map patch_operand operands in + (op, new_operands) +;; + +let emit_elem (t :symbol_table) ({ asm = a; _ } : elem) : sbyte list = match a with +| Text il -> List.fold_right (fun ins acc -> (sbytes_of_ins ins) @ acc) (List.map (patch_ins t) il) [] +| Data dl -> List.fold_right (fun d acc -> (sbytes_of_data d) @ acc) (List.map (patch_data t) dl) [] +;; + +let assemble (p : prog) : exec = + let txts = + let append_if_text e acc = match e with + | { asm = Text _; _ } -> e :: acc + | _ -> acc + in + List.fold_right append_if_text p [] + in + let txts_size = List.fold_left (fun acc e -> acc +. (elem_is_size e)) 0L txts in + let dtas = + let append_if_data e acc = match e with + | { asm = Data _; _ } -> e :: acc + | _ -> acc + in + List.fold_right append_if_data p [] + in + let dtas_size = List.fold_left (fun acc e -> acc +. (elem_ds_size e)) 0L dtas in + let ordered_prog = txts @ dtas in + let sym_tbl = build_symbol_table ordered_prog in + let entry = match (List.assoc_opt "main" sym_tbl) with + | Some q -> q + | None -> raise (Undefined_sym "main") + in + let ee = emit_elem sym_tbl in + let d_seg = List.fold_right (fun d acc -> (ee d) @ acc) dtas [] in + let t_seg = List.fold_right (fun t acc -> (ee t) @ acc) txts [] in + { + entry = entry; + text_pos = mem_bot; + data_pos = mem_bot +. txts_size; + text_seg = t_seg; + data_seg = d_seg; + } +;; (* Convert an object file into an executable machine state. - allocate the mem array diff --git a/hw2/test/gradedtests.ml b/hw2/test/gradedtests.ml index 6b29ab6..1db9232 100644 --- a/hw2/test/gradedtests.ml +++ b/hw2/test/gradedtests.ml @@ -558,7 +558,7 @@ let ins_writeback_tests = 99L) ] - let load_chunk_size_tests= +let load_chunk_size_tests= let inss = [ (Movq, [~$42; ~%Rax]); (Movq, [~$43; ~%Rbx]);