yazdmich

Untitled

Nov 13th, 2014
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.01 KB | None | 0 0
  1. #!/usr/local/bin/python3
  2.  
  3. class RAM:
  4. '''Simple RAM interface and storage object'''
  5. def __init__(self):
  6. self.image = [['00' for _ in range(16)] for _ in range(16)]
  7.  
  8. def get(self, location):
  9. x, y = divmod(int(location, 16), 16)
  10. return self.image[x][y]
  11.  
  12. def put(self, location, data):
  13. x, y = divmod(int(location, 16), 16)
  14. self.image[x][y] = data.zfill(2).upper()
  15.  
  16. def show(self):
  17. for line in self.image:
  18. print(line)
  19.  
  20. jumps = {'JMP': 'C0',
  21. 'JZ': 'C1',
  22. 'JNZ': 'C2',
  23. 'JS': 'C3',
  24. 'JNS': 'C4',
  25. 'JO': 'C5',
  26. 'JNO': 'C6'}
  27. table = {
  28. 'arithmetic': {
  29. 'ADD': ['A0', 'B0'],
  30. 'SUB': ['A1', 'B1'],
  31. 'MUL': ['A2', 'B2'],
  32. 'DIV': ['A3', 'B3'],
  33. 'MOD': ['A6', 'B6']},
  34. 'INC': 'A4',
  35. 'DEC': 'A5',
  36. 'jumps': jumps,
  37. 'MOV': ['D0', 'D1', 'D2', 'D3', 'D4'],
  38. 'CMP': ['DC', 'DA', 'DB'],
  39. 'PUSH': 'E0',
  40. 'POP': 'E1'
  41. }
  42. registers = {'AL': '00', 'BL': '01', 'CL': '02', 'DL': '03'}
  43.  
  44.  
  45. def tokenize(lines):
  46. for line in lines:
  47. line = line.split(';')[0].strip('\t')
  48. if ':' in line:
  49. yield line, []
  50. continue
  51. elif 'END' in line:
  52. break
  53. line = line.split()
  54. op, args = line[0], line[1].split(',')
  55. print('Input assembly code: ', op, *args)
  56. yield op, args
  57.  
  58.  
  59. def mov(op, args):
  60. if args[0] in registers:
  61. if args[1][1:-1]:
  62. if args[1][1:-1] in registers:
  63. return 'D3', [registers[args[0]], registers[args[1][1:-1]]]
  64. else:
  65. return 'D1', [registers[args[0]], args[1][1:-1]]
  66. else:
  67. return 'D0', [registers[args[0]], args[1]]
  68. else:
  69. if args[0][1:-1] in registers:
  70. return 'D4', [registers[args[0][1:-1]], registers[args[1]]]
  71. else:
  72. return 'D2', [args[0][1:-1], registers[args[1]]]
  73.  
  74.  
  75. def parse(lines):
  76. for line in lines:
  77. op, args = line
  78. if args:
  79. if op == 'CMP':
  80. if args[1][0] == '[' and args[1][-1] == ']':
  81. op = table[op][0]
  82. args[0] = registers[args[0]]
  83. args[1] = args[1][1:-1]
  84. elif args[1] in registers:
  85. op = table[op][1]
  86. args = [registers[arg] for arg in args]
  87. else:
  88. op = table[op][2]
  89. args[0] = registers[args[0]]
  90. elif op in table['arithmetic']:
  91. if args[1] in registers:
  92. op = table['arithmetic'][op][0]
  93. args = [registers[arg] for arg in args]
  94. else:
  95. op = table['arithmetic'][op][1]
  96. args[0] = registers[args[0]]
  97. elif op in table['jumps']:
  98. op = table['jumps'][op]
  99. elif len(args) == 1 and op in table:
  100. op = table[op]
  101. args = [registers[args[0]]]
  102. elif op == 'MOV':
  103. op, args = mov(op, args)
  104. print('Generated machine code: ', op, *args)
  105. yield op, args
  106.  
  107.  
  108. def flatten(foo):
  109. for x in foo:
  110. if hasattr(x, '__iter__') and not isinstance(x, str):
  111. for y in flatten(x):
  112. yield y
  113. else:
  114. yield x
  115.  
  116.  
  117. def tohex(val):
  118. return str(hex((val) & 0xFF))[2:]
  119.  
  120.  
  121. def twos_comp(val, bits):
  122. """compute the 2's compliment of int value val"""
  123. if((val & (1 << (bits - 1))) != 0):
  124. val = val - (1 << bits)
  125. return val
  126.  
  127.  
  128. def find_jumps(program):
  129. matches = {}
  130. l = program[:]
  131. for item in l:
  132. if item.endswith(':'):
  133. matches[item[:-1]] = l.index(item)
  134. l.remove(item)
  135. for i in range(len(l)):
  136. if l[i] in jumps.values():
  137. if l[i + 1] in matches.keys():
  138. print('Jump to', l[i + 1], end='')
  139. l[i + 1] = tohex(matches[l[i + 1]] - i)
  140. print(' =', twos_comp(int(l[i + 1], 16), 8))
  141. return l
  142.  
  143.  
  144. def load(program):
  145. memory = RAM()
  146. program = find_jumps(list(flatten(parse(tokenize(program)))))
  147. for i in range(len(program)):
  148. memory.put(hex(i), program[i])
  149. return memory
  150.  
  151. program = """
  152. MOV AL,34 ;
  153. MOV [C0],AL ;
  154. MOV BL,C0 ;
  155. LOAD: ;
  156. CMP AL,30 ;
  157. JZ START ;
  158. DEC AL ;
  159. INC BL ;
  160. MOV [BL],AL ;
  161. JMP LOAD ;
  162. START: ;
  163. MOV AL,0 ; Swap register
  164. MOV BL,0 ; Swap register
  165. MOV CL,C0 ; Display pointer
  166. MOV DL,0 ; Swap counter
  167. MOV AL,20 ; Move " " to AL
  168. MOV [C5],AL ; Move AL to RAM [C5] (hardcoded for display popup)
  169. MOV AL,0 ; Reset AL for program start
  170. MAIN: ;
  171. CMP DL,5 ; Check for sorting completion (swap counter starts at 0, decrements at each comparison with a swap, increments at each comparison without a swap, value of 5 marks fully sorted with no false positives)
  172. JZ BYE ; Exit if list is sorted
  173. CMP CL,C4 ; Is the display pointer at the end of the list?
  174. JZ RESET ; If yes, jump to reset label
  175. MOV AL,[CL] ; Move value at display pointer to AL
  176. INC CL ; Increment display pointer to get next value
  177. MOV BL,[CL] ; Move value at display pointer to BL
  178. CMP AL,BL ; Is AL greater than BL?
  179. JNS SWAP ; If yes, jump to swap label
  180. CMP BL,AL ; Is BL greater than AL?
  181. JNS CHECK ; If yes, jump to check label
  182. CHECK: ;
  183. INC DL ; Increment swap counter
  184. JMP MAIN ; Jump back to main loop
  185. SWAP: ;
  186. DEC DL ; Decrement swap counter
  187. PUSH AL ; Push value 1 to stack from AL
  188. PUSH BL ; Push value 2 to stack from BL
  189. POP AL ; Pop value 2 from stack to AL
  190. POP BL ; Pop value 1 from stack to BL
  191. DEC CL ; Decrement display pointer
  192. MOV [CL],AL ; Move AL to [CL]
  193. INC CL ; Increment display pointer
  194. MOV [CL],BL ; Move BL to [CL]
  195. JMP MAIN ; Jump back to main loop
  196. RESET: ;
  197. MOV CL,C0 ; Reset display pointer to C0
  198. JMP MAIN ; Jump back to main loop
  199. BYE: ;
  200. END ; End program
  201. """
  202. load(program).show()
Advertisement
Add Comment
Please, Sign In to add comment