Assembler finished.

Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
Mariano Uvalle 2025-02-02 00:09:58 -08:00
parent 348f9a5ec3
commit ea6edf6efe
2 changed files with 110 additions and 4 deletions

View file

@ -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

View file

@ -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]);