Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # asm - assembler for hack computer
- # usage: awk -f asm.awk assembly-program-file.asm
- BEGIN {
- src_file = ARGV[1]
- tmp_file = "asm.tmp"
- out_file = substr(src_file, 1, index(src_file, ".")) "hack"
- split("0 M D DM A AM AD ADM", x)
- split("0 JGT JEQ JGE JLT JNE JLE JMP", y)
- split("000 001 010 011 100 101 110 111", b)
- for (i = 1; i <= 8; i++) {
- destc[x[i]] = b[i]
- jumpc[y[i]] = b[i]
- }
- destc["MD"] = "011"
- destc["MA"] = "101"
- destc["DA"] = "110"
- destc["DAM"] = "111"
- destc["MAD"] = "111"
- destc["MDA"] = "111"
- destc["DMA"] = "111"
- destc["AMD"] = "111"
- n = split("0 1 -1 D A !D !A -D -A D+1 A+1 D-1 A-1 D+A D-A A-D D&A D|A", z)
- split("0101010 0111111 0111010 0001100 0110000 0001101 0110001 0001111 0110011 0011111 0110111 0001110 0110010 0000010 0010011 0000111 0000000 0010101", w)
- for (i = 1; i <= n; i++)
- opc[z[i]] = w[i]
- opc["M"] = "1110000"
- opc["!M"] = "1110001"
- opc["-M"] = "1110011"
- opc["M+1"] = "1110111"
- opc["M-1"] = "1110010"
- opc["D+M"] = "1000010"
- opc["D-M"] = "1010011"
- opc["M-D"] = "1000111"
- opc["D&M"] = "1000000"
- opc["D|M"] = "1010101"
- symtab[R0] = 0
- symtab[R1] = 1
- symtab[R2] = 2
- symtab[R3] = 3
- symtab[R4] = 4
- symtab[R5] = 5
- symtab[R6] = 6
- symtab[R7] = 7
- symtab[R8] = 8
- symtab[R9] = 9
- symtab[R10] = 10
- symtab[R11] = 11
- symtab[R12] = 12
- symtab[R13] = 13
- symtab[R14] = 14
- symtab[R15] = 15
- symtab[SP] = 0
- symtab[LCL] = 1
- symtab[ARG] = 2
- symtab[THIS] = 3
- symtab[THAT] = 4
- symtab[SCREEN] = 16384
- symtab[KBD] = 24576
- # ASSEMBLER PASS 1
- while (getline <src_file > 0) {
- if (/^[[:space:]]*(\/\/.*)*$/)
- continue
- else if (/\(.*\)/) {
- symtab[substr($0, 2, length($0)-2)] = nl-ns+1
- ns++; nl++
- } else {
- # print sub(/[[:space:]]*/, "")
- print $0 >tmp_file
- nl++
- }
- }
- close(tmp_file)
- # ASSEMBLER PASS 2
- nextram = 16
- while (getline <tmp_file > 0) {
- if (/^@/) { # A-instruction
- con = substr($0, 2)
- if (con !~ /^[:digit:]+$/)
- if (con in symtab) {
- con = symtab[con]
- } else {
- symtab[con] = nextram
- con = nextram
- nextram++
- }
- binstring = ""
- for (i = 0; i < 15; i++)
- if (and(con, lshift(1,i))) {
- binstring = "1" binstring
- } else {
- binstring = "0" binstring
- }
- print "0" binstring > out_file
- } else { # C-instruction
- m = index($0, "=")
- n = index($0, ";")
- dest = m ? substr($0, 1, m-1) : 0
- comm = n ? substr($0, m+1, n-m-1) : substr($0, m+1)
- jump = n ? substr($0, n+1) : 0
- print comm
- printf("comm %s; jump %s\n", comm, jump)
- printf("111%s%s%s\n", opc[op], destc[dest], jumpc[jump]) > out_file
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement