从for循环到机器码


def p(*x): print(x)
p(type(range), dir(range))
r = range(2); i = iter(r)
try: p(next(i)); p(next(i)); p(next(i))
except Exception as e: p(e)
def fn():
	n = 0
	for i in range(3): n = n + i
fn()
import dis
dis.dis(fn)

(, ['__bool__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop'])

(0,)
(1,)
(StopIteration(),)
7 0 LOAD_CONST 1 (0)
2 STORE_FAST 0 (n)
8 4 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 2 (3)
8 CALL_FUNCTION 1
10 GET_ITER
>> 12 FOR_ITER 12 (to 26)
14 STORE_FAST 1 (i)
16 LOAD_FAST 0 (n)
18 LOAD_FAST 1 (i)
20 BINARY_ADD
22 STORE_FAST 0 (n)
24 JUMP_ABSOLUTE 12

# -*- coding: utf-8 -*-
import re
mem = [x for x in re.split('[\r|\n]', '''
	store a 1
	store b 2
	add a 1
	add 	b -1
	jlz 2
	jmp -3
	jmp 0
'''.lower()) if x != '']
# register file: 装register的柜子。register: 登记簿 pc: program counter
reg_file = { 'pc': 0 }
msb = 0 # most significat bit, 符号位
while True:
	instruction = mem[reg_file['pc']] # fetch instruction 取指
	print('"' + instruction + '"', end='\t')
	instruction = instruction.split() # 译码
	op_code = instruction[0] # op: operation
	if op_code == 'store':
		(reg_name, immd) = instruction[1:]
		reg_file[reg_name] = int(immd)
		reg_file['pc'] += 1
	elif op_code == 'add':
		(reg_name, immd) = instruction[1:]
		reg_file[reg_name] += int(immd)
		if reg_file[reg_name] < 0: msb = 1
		reg_file['pc'] += 1
	elif op_code == 'jlz': # jump if less than 0
		immd = int(instruction[1])
		if msb: reg_file['pc'] += immd
		else: reg_file['pc'] += 1
	elif op_code == 'jmp':
		immd = int(instruction[1])
		if immd == 0: break
		reg_file['pc'] += immd
	print('\t', reg_file, ' msb=', msb, sep='')
	input('Press the Enter key')
from functools import reduce
def bits(n, b = 0): return list(map(lambda x:b,list(range(n))))
class ROM:
	def __init__(m):
		m.bytes = (
			( 0, 0, 0, 0, 0, 0, 0, 1 ), # store a 1
			( 0, 0, 1, 0, 0, 0, 1, 0 ), # store b 2
			( 0, 1, 0, 0, 0, 0, 0, 1 ), # add a 1
			( 0, 1, 1, 1, 1, 1, 1, 1 ), # add b -1
			( 1, 0, 0, 0, 0, 0, 1, 0 ), # jlz 2
			( 1, 1, 0, 1, 1, 1, 0, 1 ), # jmp -3
			( 1, 1, 0, 0, 0, 0, 0, 0 ), # jmp 0
		)
		m.a = m.d = bits(8) # They will have different id() after being assigned
	def read(m): m.d = m.bytes[reduce(lambda hi, low: hi * 2 + low, m.a, 0)]