Assembler, Part 2

April 18, 2014

In the previous exercise we built an assembler for a hypothetical computer. Today we write a simulator for that hypothetical computer. The basic idea is simple: Start with a program counter at location 0, either perform the action at the location and advance the program counter to the next location, or set the program counter to the object of a jump instruction.

Your task is to write the simulator. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Advertisement

Pages: 1 2

2 Responses to “Assembler, Part 2”

  1. Mike said

    Simulator in python

    
    def run(memory):
        accumulator = 0
        pc = 0
    
        while True:
            op, arg = divmod(memory[pc], 1000)
    
            if 1 <= op <= 6:
                if   op == 1: accumulator = int(input('? '))
                elif op == 2: print(accumulator)
                elif op == 3: accumulator = memory[arg]
                elif op == 4: memory[arg] = accumulator
                elif op == 5: accumulator = (accumulator + memory[arg]) % 100000
                elif op == 6: accumulator = (accumulator - memory[arg]) % 100000
    
                pc = (pc + 1) % 1000
    
            elif 7 <= op <= 9:
                if   op == 7: test = 0 < accumulator < 50000 # 10's complement ?
                elif op == 8: test = accumulator == 0
                elif op == 9: test = True
    
                pc = arg if test else (pc + 1)
                
            elif op == 10: # halt
                break
    
            else:
                fmt = "Trap: invalid instruction '{:05}' at location '{:03}'."
                print(fmt.format(memory[pc], pc))
                break
    
    
  2. (defn delta [C]
      (let [pc (:pc C)
            instr (aget (:M C) pc)
            opc ((clojure.set/map-invert (:opc C)) (apply str (take 2 instr)))
            arg (Integer/parseInt (apply str (nthrest instr 2)))
            C (assoc C :pc (inc pc))]
        (condp = opc
          "get"   (assoc C :acc (Integer/parseInt (read-line)))
          "put"   (println (:acc C))
          "ld"    (assoc C :acc (aget (:M C) arg))
          "st"    (do
                    (aset (:M C) arg (str (:acc C)))
                    C)
          "add"   (assoc C :acc (+ (:acc C) (Integer/parseInt (aget (:M C) arg))))
          "sub"   (assoc C :acc (- (:acc C) (Integer/parseInt (aget (:M C) arg))))
          "jpos"  (if (< 0 (:acc C)) (assoc C :pc arg) C)
          "jz"    (if (= 0 (:acc C)) (assoc C :pc arg) C)
          "j"     (assoc C :pc arg)
          "halt"  (dissoc C :pc)
          :default C)))
    
    (defn run [C code]
      (loop [C (load-asm C code)]
        (if (:pc C)
          (recur (delta C))
          C)))
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: