Assembler finished.
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
parent
348f9a5ec3
commit
ea6edf6efe
2 changed files with 110 additions and 4 deletions
|
|
@ -406,9 +406,115 @@ exception Redefined_sym of lbl
|
||||||
|
|
||||||
HINT: List.fold_left and List.fold_right are your friends.
|
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"
|
exception UnexpectedData
|
||||||
let assemble (p : prog) : exec = failwith "assemble unimplemented"
|
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.
|
(* Convert an object file into an executable machine state.
|
||||||
- allocate the mem array
|
- allocate the mem array
|
||||||
|
|
|
||||||
|
|
@ -558,7 +558,7 @@ let ins_writeback_tests =
|
||||||
99L)
|
99L)
|
||||||
]
|
]
|
||||||
|
|
||||||
let load_chunk_size_tests=
|
let load_chunk_size_tests=
|
||||||
let inss = [
|
let inss = [
|
||||||
(Movq, [~$42; ~%Rax]);
|
(Movq, [~$42; ~%Rax]);
|
||||||
(Movq, [~$43; ~%Rbx]);
|
(Movq, [~$43; ~%Rbx]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue