(* finalize.ml 15-411 by Roland Flury modified 15 Sep 2004 by Arthur O'Dwyer *) (* @version $Id: finalize.ml,v 1.3 2004/10/30 19:33:22 ajo Exp $ *) module HA = Hashtbl module A = Assem open Types (* Produces the output by replacing the temps by strings in the instructions. |prog| is a list of instructions. |file_Name| is the name of the source file. *) let finalize_prog (prog, numslots, raf) file_Name = (* Make an arbitrary string quote-safe *) let quote s = begin let s = Str.global_replace (Str.regexp_string "\\") "\\\\" s in let s = Str.global_replace (Str.regexp_string "\"") "\\\"" s in s end in (* Returns a string-representation for a temporary *) let temp2string temp = match (raf temp) with | REGISTER(1) -> "%eax" | REGISTER(2) -> "%ebx" | REGISTER(3) -> "%ecx" | REGISTER(4) -> "%edx" | REGISTER(5) -> "%esi" | REGISTER(6) -> "%edi" | REGISTER(7) -> "%ebp" | REGISTER(8) -> "%esp" | REGISTER(r) -> begin (Printf.printf "Register %d does not exist\n" r); "" end | STACKSLOT(i) -> Printf.sprintf "%d(%%ebp)" (-4*i) | _ -> begin (Printf.printf "Serious bug here!"); "" end in let prog_str = List.fold_left (fun res i -> res ^ (A.format temp2string i)) "" prog in begin (Printf.sprintf "\t.file\t\"%s\"\n" (quote file_Name))^ "\t.section\t.rodata\n"^ ".Lfilename:\n"^ (Printf.sprintf "\t.string \"%s\"\n" (quote file_Name))^ ".Lnpd:\t.string \"Null pointer dereference\"\n"^ ".Lbpb:\t.string \"Pointer out of range below\"\n"^ ".Lbpa:\t.string \"Pointer out of range above\"\n"^ ".Ldvz:\t.string \"Division by zero attempted\"\n"^ ".Ldmz:\t.string \"Modulo by zero attempted\"\n"^ ".Lnullptr:\n"^ "\t.long 0\n"^ "\t.long 0\n"^ "\t.long 0\n"^ "\t.text\n"^ ".globl\t_l2_main\n"^ "\t.type\t_l2_main,@function\n"^ ".globl\t_null_dereference\n"^ "\t.type\t_null_dereference,@function\n"^ "_l2_main:\n"^ "\tpushl\t%ebp\n"^ "\tpushl\t%ebx\n"^ "\tpushl\t%esi\n"^ "\tpushl\t%edi\n"^ "\tmovl\t%esp, %ebp\n"^ begin if numslots > 0 then (Printf.sprintf "\tsubl\t$%d, %%esp\n" (4*numslots)) else "" end^ prog_str^ "\tmovl\t%ebp, %esp\n"^ "\tpopl\t%edi\n"^ "\tpopl\t%esi\n"^ "\tpopl\t%ebx\n"^ "\tpopl\t%ebp\n"^ "\tret\n"^ "_null_dereference:\n"^ "\tpushl\t%ebp\n"^ "\tmovl\t%esp, %ebp\n"^ "\tsubl\t$24, %esp\n"^ "\tmovl\t12(%ebp), %edx\n"^ "\tmovl\t8(%ebp), %ecx\n"^ "\tmovl\t(%edx), %eax\n"^ "\ttestl\t%eax, %eax\n"^ "\tjne\t.Lnd1\n"^ "\tmovl\t$.Lnpd, 8(%esp)\n"^ "\tjmp\t.Lnd3\n"^ "\t.p2align 4,,7\n"^ ".Lnd1:\tmovl\t8(%edx), %eax\n"^ "\tcmpl\t%eax, 4(%edx)\n"^ "\tjge\t.Lnd2\n"^ "\tmovl\t$.Lbpb, 8(%esp)\n"^ "\tjmp\t.Lnd3\n"^ "\t.p2align 4,,7\n"^ ".Lnd2:\tmovl\t$.Lbpa, 8(%esp)\n"^ ".Lnd3:\tmovl\t%ecx, 4(%esp)\n"^ "\tmovl\t$.Lfilename, (%esp)\n"^ "\tcall\t_l2_error\n"^ "#\tassembly output complete\n" end