Merge branch 'master' of https://git.serveurtom.fr/Tom/24H_du_code_2026
This commit is contained in:
commit
a4cc3b36a6
@ -13,9 +13,9 @@ _loop:
|
|||||||
MOV R0 R1 ; a = b
|
MOV R0 R1 ; a = b
|
||||||
MOV R1 R3 ; b = c
|
MOV R1 R3 ; b = c
|
||||||
|
|
||||||
CMP R0 R1
|
CMP R1 R0
|
||||||
JLT _end ; end si b < a
|
JLT _end ; end si b < a
|
||||||
JMP _loop
|
JMP _loop
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
RET
|
RET
|
||||||
263
Epreuve3.py
Normal file
263
Epreuve3.py
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
# ---------------------------------------------------------
|
||||||
|
# Simulateur
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# - Bus données : 8 bits
|
||||||
|
# - 4 registres R0..R3 (8 bits)
|
||||||
|
# - Bus adresse : 8 bits
|
||||||
|
# - RAM : 256 octets
|
||||||
|
# - Instructions : 1 ou 2 octets
|
||||||
|
# - Cycles : 1 octet -> 1, 2 octets -> 2, LDR/STR -> 3
|
||||||
|
# - PC démarre à 0
|
||||||
|
# - Pile descendante, SP=255
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CPU:
|
||||||
|
pc: int = 0
|
||||||
|
sp: int = 255
|
||||||
|
regs: list = field(default_factory=list) # R0..R3
|
||||||
|
lt: int = 0 # flag LT
|
||||||
|
eq: int = 0 # flag EQ
|
||||||
|
cycles: int = 0
|
||||||
|
running: bool = True
|
||||||
|
after_ret: bool = False
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
if not self.regs:
|
||||||
|
self.regs = [0, 0, 0, 0]
|
||||||
|
|
||||||
|
|
||||||
|
class Simulator:
|
||||||
|
def __init__(self, program: bytes):
|
||||||
|
self.ram = bytearray(256)
|
||||||
|
for i, b in enumerate(program[:256]):
|
||||||
|
self.ram[i] = b
|
||||||
|
self.cpu = CPU()
|
||||||
|
self.program_size = len(program)
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------- utilitaires mémoire / pile -----------------
|
||||||
|
|
||||||
|
def fetch_byte(self) -> int:
|
||||||
|
b = self.ram[self.cpu.pc]
|
||||||
|
self.cpu.pc = (self.cpu.pc + 1) & 0xFF
|
||||||
|
return b
|
||||||
|
|
||||||
|
def push(self, value: int):
|
||||||
|
if self.cpu.sp < 0:
|
||||||
|
raise RuntimeError("STACK OVERFLOW")
|
||||||
|
self.ram[self.cpu.sp] = value & 0xFF
|
||||||
|
self.cpu.sp -= 1
|
||||||
|
|
||||||
|
def pop(self) -> int:
|
||||||
|
if self.cpu.sp >= 255:
|
||||||
|
return 0
|
||||||
|
self.cpu.sp += 1
|
||||||
|
return self.ram[self.cpu.sp]
|
||||||
|
|
||||||
|
# ----------------- exécution d'une instruction -----------------
|
||||||
|
|
||||||
|
def step(self):
|
||||||
|
c = self.cpu
|
||||||
|
pc_before = c.pc
|
||||||
|
b = self.fetch_byte()
|
||||||
|
|
||||||
|
instr = ""
|
||||||
|
size = 1 # taille en octets (1 ou 2)
|
||||||
|
extra_cycles = 0 # pour LDR/STR/TIM
|
||||||
|
|
||||||
|
# --- instructions 2 octets à opcode fixe ---
|
||||||
|
#print(pc_before)
|
||||||
|
#print(self.program_size)
|
||||||
|
if c.after_ret:
|
||||||
|
instr = f"DB 0x{b:02X}"
|
||||||
|
|
||||||
|
elif b == 0x00: # CALL _label
|
||||||
|
addr = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"CALL {addr}"
|
||||||
|
self.push(c.pc)
|
||||||
|
c.pc = addr
|
||||||
|
|
||||||
|
elif b == 0x40: # JMP _label
|
||||||
|
addr = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"JMP {addr}"
|
||||||
|
c.pc = addr
|
||||||
|
|
||||||
|
elif b == 0xC0: # JLT _label
|
||||||
|
addr = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"JLT {addr}"
|
||||||
|
if c.lt == 1:
|
||||||
|
c.pc = addr
|
||||||
|
|
||||||
|
elif b == 0x20: # JEQ _label
|
||||||
|
addr = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"JEQ {addr}"
|
||||||
|
if c.eq == 1:
|
||||||
|
c.pc = addr
|
||||||
|
|
||||||
|
elif b == 0x80: # RET
|
||||||
|
instr = "RET"
|
||||||
|
ret = self.pop()
|
||||||
|
if c.sp >= 255 and ret == 0:
|
||||||
|
c.after_ret = True
|
||||||
|
c.running = False
|
||||||
|
else:
|
||||||
|
c.pc = ret
|
||||||
|
|
||||||
|
# --- PUSH / POP ---
|
||||||
|
elif (b & 0b11111100) == 0b10100000: # PUSH Rx
|
||||||
|
r = b & 0b11
|
||||||
|
instr = f"PUSH R{r}"
|
||||||
|
self.push(c.regs[r])
|
||||||
|
|
||||||
|
elif (b & 0b11111100) == 0b01100000: # POP Rx
|
||||||
|
r = b & 0b11
|
||||||
|
instr = f"POP R{r}"
|
||||||
|
c.regs[r] = self.pop()
|
||||||
|
|
||||||
|
# --- MOV Rx valeur / SUB Rx valeur / CMP Rx valeur ---
|
||||||
|
elif (b & 0b11111100) == 0b11100000: # MOV Rx valeur
|
||||||
|
r = b & 0b11
|
||||||
|
imm = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"MOV R{r}, {imm}"
|
||||||
|
c.regs[r] = imm
|
||||||
|
|
||||||
|
elif (b & 0b11111100) == 0b00010000: # SUB Rx valeur
|
||||||
|
r = b & 0b11
|
||||||
|
imm = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"SUB R{r}, {imm}"
|
||||||
|
c.regs[r] = (c.regs[r] - imm) & 0xFF
|
||||||
|
|
||||||
|
elif (b & 0b11111100) == 0b10010000: # CMP Rx valeur
|
||||||
|
r = b & 0b11
|
||||||
|
imm = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"CMP R{r}, {imm}"
|
||||||
|
v = c.regs[r]
|
||||||
|
c.lt = 1 if v < imm else 0
|
||||||
|
c.eq = 1 if v == imm else 0
|
||||||
|
|
||||||
|
# --- MOV / SUB / CMP registre-registre ---
|
||||||
|
elif (b & 0b11110000) == 0b01010000: # MOV Rx Ry
|
||||||
|
dst = (b >> 2) & 0b11
|
||||||
|
src = b & 0b11
|
||||||
|
instr = f"MOV R{dst}, R{src}"
|
||||||
|
c.regs[dst] = c.regs[src]
|
||||||
|
|
||||||
|
elif (b & 0b11110000) == 0b11010000: # SUB Rx Ry
|
||||||
|
dst = (b >> 2) & 0b11
|
||||||
|
src = b & 0b11
|
||||||
|
instr = f"SUB R{dst}, R{src}"
|
||||||
|
c.regs[dst] = (c.regs[dst] - c.regs[src]) & 0xFF
|
||||||
|
|
||||||
|
elif (b & 0b11110000) == 0b00110000: # CMP Rx Ry
|
||||||
|
dst = (b >> 2) & 0b11
|
||||||
|
src = b & 0b11
|
||||||
|
instr = f"CMP R{dst}, R{src}"
|
||||||
|
v1 = c.regs[dst]
|
||||||
|
v2 = c.regs[src]
|
||||||
|
c.lt = 1 if v1 < v2 else 0
|
||||||
|
c.eq = 1 if v1 == v2 else 0
|
||||||
|
|
||||||
|
# --- LDR / STR (2 octets, 3 cycles) ---
|
||||||
|
elif (b & 0b11110000) == 0b10110000: # LDR Rx Ry _label
|
||||||
|
dst = (b >> 2) & 0b11
|
||||||
|
src = b & 0b11
|
||||||
|
addr = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"LDR R{dst}, R{src}, {addr}"
|
||||||
|
eff = (addr + c.regs[src]) & 0xFF
|
||||||
|
c.regs[dst] = self.ram[eff]
|
||||||
|
extra_cycles = 1 # 2 octets -> 2 cycles +1 = 3
|
||||||
|
|
||||||
|
elif (b & 0b11110000) == 0b01110000: # STR Rx Ry _label
|
||||||
|
dst = (b >> 2) & 0b11
|
||||||
|
src = b & 0b11
|
||||||
|
addr = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
instr = f"STR R{dst}, R{src}, {addr}"
|
||||||
|
eff = (addr + c.regs[src]) & 0xFF
|
||||||
|
self.ram[eff] = c.regs[dst] & 0xFF
|
||||||
|
extra_cycles = 1
|
||||||
|
|
||||||
|
# --- OUT Rx ---
|
||||||
|
elif (b & 0b11111100) == 0b11110000: # OUT Rx
|
||||||
|
r = b & 0b11
|
||||||
|
instr = f"OUT R{r}"
|
||||||
|
print(f"[OUT] R{r} = {c.regs[r]}")
|
||||||
|
|
||||||
|
# --- TIM valeur ---
|
||||||
|
elif b == 0xF8: # TIM
|
||||||
|
second = self.fetch_byte()
|
||||||
|
size = 2
|
||||||
|
m = (second >> 7) & 0x1
|
||||||
|
v = second & 0x7F
|
||||||
|
instr = f"TIM m={m}, v={v}"
|
||||||
|
mult = 1 if m == 0 else 100
|
||||||
|
pause_ms = mult * (v + 1)
|
||||||
|
c.cycles += pause_ms # modélisation de la pause
|
||||||
|
|
||||||
|
# if pc_before >= self.program_size:
|
||||||
|
# if 32 <= b <= 126:
|
||||||
|
# instr = f"DB 0x{b:02X} ('{chr(b)}')"
|
||||||
|
# else:
|
||||||
|
# instr = f"DB 0x{b:02X}"
|
||||||
|
else:
|
||||||
|
instr = f"UNKNOWN 0x{b:02X}"
|
||||||
|
c.running = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# calcul des cycles
|
||||||
|
if (b & 0b11110000) in (0xB0, 0x70): # LDR / STR
|
||||||
|
c.cycles += 3
|
||||||
|
cycles_added = 3
|
||||||
|
else:
|
||||||
|
c.cycles += size
|
||||||
|
cycles_added = size
|
||||||
|
|
||||||
|
self.report(pc_before, instr, cycles_added)
|
||||||
|
|
||||||
|
# ----------------- rapport d'exécution -----------------
|
||||||
|
|
||||||
|
def report(self, pc_before: int, instr: str, cycles_added: int):
|
||||||
|
c = self.cpu
|
||||||
|
regs_str = " ".join(f"R{i}={c.regs[i]:02X}" for i in range(4))
|
||||||
|
print(f"PC={pc_before:02X} {instr:20s} +Cycles={cycles_added:3d} Total={c.cycles}")
|
||||||
|
print(f" {regs_str} LT={c.lt} EQ={c.eq} SP={c.sp}")
|
||||||
|
print("-" * 60)
|
||||||
|
|
||||||
|
# ----------------- boucle principale -----------------
|
||||||
|
|
||||||
|
def run(self, max_steps: int = 100000):
|
||||||
|
steps = 0
|
||||||
|
while self.cpu.running and steps < max_steps:
|
||||||
|
self.step()
|
||||||
|
steps += 1
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# LECTURE D'UN FICHIER .bin ET LANCEMENT
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Nom du fichier binaire à exécuter
|
||||||
|
path =""
|
||||||
|
args= sys.argv
|
||||||
|
if (len(args) > 1):
|
||||||
|
filename = args[1]
|
||||||
|
print("filename: " + filename)
|
||||||
|
with open(filename, "rb") as f:
|
||||||
|
program = f.read()
|
||||||
|
sim = Simulator(program)
|
||||||
|
sim.run()
|
||||||
|
else:
|
||||||
|
print("Needs *.bin as parameter")
|
||||||
BIN
__pycache__/assembleur.cpython-314.pyc
Normal file
BIN
__pycache__/assembleur.cpython-314.pyc
Normal file
Binary file not shown.
318
assembleur.py
318
assembleur.py
@ -1,13 +1,16 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
instructions = {
|
instructions = {
|
||||||
"DB" : {
|
"DB" : {
|
||||||
|
"ins": "DB",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": False,
|
"isRegister": False,
|
||||||
"isValue": True,
|
"isValue": True,
|
||||||
"isLabel": False
|
"isLabel": False,
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"CALL": {
|
"CALL": {
|
||||||
|
"ins": "CALL",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": False,
|
"isRegister": False,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -15,9 +18,11 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"RET": {
|
"RET": {
|
||||||
|
"ins": "RET",
|
||||||
"args": []
|
"args": []
|
||||||
},
|
},
|
||||||
"JMP": {
|
"JMP": {
|
||||||
|
"ins": "JMP",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": False,
|
"isRegister": False,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -25,6 +30,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"JLT": {
|
"JLT": {
|
||||||
|
"ins": "JLT",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": False,
|
"isRegister": False,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -32,6 +38,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"JEQ": {
|
"JEQ": {
|
||||||
|
"ins": "JEQ",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": False,
|
"isRegister": False,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -39,6 +46,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"PUSH": {
|
"PUSH": {
|
||||||
|
"ins": "PUSH",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": True,
|
"isRegister": True,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -46,6 +54,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"POP": {
|
"POP": {
|
||||||
|
"ins": "POP",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": True,
|
"isRegister": True,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -53,6 +62,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"MOV": {
|
"MOV": {
|
||||||
|
"ins": "MOV",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": True,
|
"isRegister": True,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -65,6 +75,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"SUB": {
|
"SUB": {
|
||||||
|
"ins": "SUB",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": True,
|
"isRegister": True,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -77,6 +88,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"CMP": {
|
"CMP": {
|
||||||
|
"ins": "CMP",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": True,
|
"isRegister": True,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -89,6 +101,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"LDR": {
|
"LDR": {
|
||||||
|
"ins": "LDR",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": True,
|
"isRegister": True,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -106,6 +119,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"STR": {
|
"STR": {
|
||||||
|
"ins": "STR",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": True,
|
"isRegister": True,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -123,6 +137,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"OUT": {
|
"OUT": {
|
||||||
|
"ins": "OUT",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": True,
|
"isRegister": True,
|
||||||
"isValue": False,
|
"isValue": False,
|
||||||
@ -130,6 +145,7 @@ instructions = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"TIM": {
|
"TIM": {
|
||||||
|
"ins": "TIM",
|
||||||
"args": [{
|
"args": [{
|
||||||
"isRegister": False,
|
"isRegister": False,
|
||||||
"isValue": True,
|
"isValue": True,
|
||||||
@ -138,5 +154,303 @@ instructions = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labels = {}
|
||||||
|
|
||||||
|
def valueToInt(arg):
|
||||||
|
try:
|
||||||
|
return int(arg)
|
||||||
|
except:
|
||||||
|
return ord(arg)
|
||||||
|
|
||||||
|
def registerToDec(reg):
|
||||||
|
return int(reg[1])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def testArgIsRegister(arg):
|
||||||
|
if (len(arg) != 2):
|
||||||
|
return False
|
||||||
|
if (arg[0] != "R"):
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
val = int(arg[1])
|
||||||
|
if (0 <= val <= 3):
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
def testArgIsValue(arg):
|
||||||
|
# Test 0 - 255
|
||||||
|
try:
|
||||||
|
val = int(arg)
|
||||||
|
if (0 <= val <= 255):
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Test 'a' 'A' '0'
|
||||||
|
if (len(arg) == 3):
|
||||||
|
if (arg[0] == arg[2] == "'"):
|
||||||
|
if ((ord('a') <= ord(arg[1]) <= ord('z')) or (ord('A') <= ord(arg[1]) <= ord('Z')) or (ord('0') <= ord(arg[1]) <= ord('9'))):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def testArgIsLabel(arg, twoDotsIncluded = False):
|
||||||
|
if (len(arg) == 0):
|
||||||
|
return False
|
||||||
|
if (arg[0] != "_"):
|
||||||
|
return False
|
||||||
|
if (twoDotsIncluded):
|
||||||
|
if (arg[-1] != ":"):
|
||||||
|
return False
|
||||||
|
if (set(arg[1:-1]) <= set("abcdefghijklmnopqrstuvwxyz0123456789")):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if (set(arg[1:]) <= set("abcdefghijklmnopqrstuvwxyz0123456789")):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def convertInsDB(args):
|
||||||
|
value = valueToInt(args[0])
|
||||||
|
return {"opcode": [value], "DB": True}
|
||||||
|
|
||||||
|
def convertInsCALL(args):
|
||||||
|
|
||||||
|
return {"opcode": [0b00000000, "label"], "label": args[0], "offset": 0}
|
||||||
|
|
||||||
|
def convertInsRET(args):
|
||||||
|
|
||||||
|
return {"opcode": [0b10000000]}
|
||||||
|
|
||||||
|
def convertInsJMP(args):
|
||||||
|
|
||||||
|
return {"opcode": [0b01000000, "label"], "label": args[0], "offset": 0}
|
||||||
|
|
||||||
|
def convertInsJLT(args):
|
||||||
|
|
||||||
|
return {"opcode": [0b11000000, "label"], "label": args[0], "offset": 0}
|
||||||
|
|
||||||
|
def convertInsJEQ(args):
|
||||||
|
|
||||||
|
return {"opcode": [0b00100000, "label"], "label": args[0], "offset": 0}
|
||||||
|
|
||||||
|
def convertInsPUSH(args):
|
||||||
|
idReg0 = registerToDec(args[0])
|
||||||
|
return {"opcode": [0b10100000 | idReg0]}
|
||||||
|
|
||||||
|
def convertInsPOP(args):
|
||||||
|
idReg0 = registerToDec(args[0])
|
||||||
|
return {"opcode": [0b01100000 | idReg0]}
|
||||||
|
|
||||||
|
def convertInsMOV(args):
|
||||||
|
idReg0 = registerToDec(args[0])
|
||||||
|
print("idReg0", idReg0)
|
||||||
|
if (testArgIsRegister(args[1])):
|
||||||
|
idReg1 = registerToDec(args[1])
|
||||||
|
print("idReg0", idReg1)
|
||||||
|
return {"opcode": [0b01010000 | (idReg0 << 2) | (idReg1)]}
|
||||||
|
value = valueToInt(args[1])
|
||||||
|
return {"opcode": [0b11100000 | (idReg0), value]}
|
||||||
|
|
||||||
|
|
||||||
|
def convertInsSUB(args):
|
||||||
|
idReg0 = registerToDec(args[0])
|
||||||
|
print("idReg0", idReg0)
|
||||||
|
if (testArgIsRegister(args[1])):
|
||||||
|
idReg1 = registerToDec(args[1])
|
||||||
|
print("idReg0", idReg1)
|
||||||
|
return {"opcode": [0b11010000 | (idReg0 << 2) | (idReg1)]}
|
||||||
|
value = valueToInt(args[1])
|
||||||
|
return {"opcode": [0b00010000 | (idReg0), value]}
|
||||||
|
|
||||||
|
def convertInsCMP(args):
|
||||||
|
idReg0 = registerToDec(args[0])
|
||||||
|
print("idReg0", idReg0)
|
||||||
|
if (testArgIsRegister(args[1])):
|
||||||
|
idReg1 = registerToDec(args[1])
|
||||||
|
print("idReg0", idReg1)
|
||||||
|
return {"opcode": [0b00110000 | (idReg0 << 2) | (idReg1)]}
|
||||||
|
value = valueToInt(args[1])
|
||||||
|
return {"opcode": [0b10010000 | (idReg0), value]}
|
||||||
|
|
||||||
|
def convertInsLDR(args):
|
||||||
|
idReg0 = registerToDec(args[0])
|
||||||
|
idReg1 = registerToDec(args[1])
|
||||||
|
return {"opcode": [0b10110000 | (idReg0 << 2) | (idReg1), valueToInt(args[2]), "label"], "label": args[0], "offset": 0}
|
||||||
|
|
||||||
|
def convertInsSTR(args):
|
||||||
|
idReg0 = registerToDec(args[0])
|
||||||
|
idReg1 = registerToDec(args[1])
|
||||||
|
return {"opcode": [0b01110000 | (idReg0 << 2) | (idReg1), valueToInt(args[2]), "label"], "label": args[0], "offset": 0}
|
||||||
|
|
||||||
|
def convertInsOUT(args):
|
||||||
|
|
||||||
|
return {"opcode": [0b11110000]}
|
||||||
|
|
||||||
|
def convertInsTIM(args):
|
||||||
|
|
||||||
|
value = valueToInt(args[0])
|
||||||
|
return {"opcode": [0b11111000, value]}
|
||||||
|
|
||||||
|
def testArg(arg, insArg):
|
||||||
|
valid = False
|
||||||
|
# Test for isRegister
|
||||||
|
if (insArg["isRegister"] and testArgIsRegister(arg)):
|
||||||
|
valid = True
|
||||||
|
|
||||||
|
# Test for isValue
|
||||||
|
if (insArg["isValue"] and testArgIsValue(arg)):
|
||||||
|
valid = True
|
||||||
|
|
||||||
|
# Test for isLabel
|
||||||
|
if (insArg["isLabel"] and testArgIsLabel(arg)):
|
||||||
|
valid = True
|
||||||
|
|
||||||
|
if (not valid):
|
||||||
|
print(f"ERROR : Arg {arg} not valid !")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def decodeInstruction(args, ins):
|
||||||
|
for i in range(0, len(args)):
|
||||||
|
testArg(args[i], ins["args"][i])
|
||||||
|
|
||||||
|
if (ins["ins"] == "DB"):
|
||||||
|
return convertInsDB(args)
|
||||||
|
elif (ins["ins"] == "CALL") :
|
||||||
|
return convertInsCALL(args)
|
||||||
|
elif (ins["ins"] == "RET") :
|
||||||
|
return convertInsRET(args)
|
||||||
|
elif (ins["ins"] == "JMP") :
|
||||||
|
return convertInsJMP(args)
|
||||||
|
elif (ins["ins"] == "JLT") :
|
||||||
|
return convertInsJLT(args)
|
||||||
|
elif (ins["ins"] == "JEQ") :
|
||||||
|
return convertInsJEQ(args)
|
||||||
|
elif (ins["ins"] == "PUSH") :
|
||||||
|
return convertInsPUSH(args)
|
||||||
|
elif (ins["ins"] == "POP") :
|
||||||
|
return convertInsPOP(args)
|
||||||
|
elif (ins["ins"] == "MOV") :
|
||||||
|
return convertInsMOV(args)
|
||||||
|
elif (ins["ins"] == "SUB") :
|
||||||
|
return convertInsSUB(args)
|
||||||
|
elif (ins["ins"] == "CMP") :
|
||||||
|
return convertInsCMP(args)
|
||||||
|
elif (ins["ins"] == "LDR") :
|
||||||
|
return convertInsLDR(args)
|
||||||
|
elif (ins["ins"] == "STR") :
|
||||||
|
return convertInsSTR(args)
|
||||||
|
elif (ins["ins"] == "OUT") :
|
||||||
|
return convertInsOUT(args)
|
||||||
|
elif (ins["ins"] == "TIM") :
|
||||||
|
return convertInsTIM(args)
|
||||||
|
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def decodeLine(line, PC):
|
||||||
|
commentPos = line.find(";")
|
||||||
|
if (commentPos != -1):
|
||||||
|
line = line[:line.find(";")]
|
||||||
|
line = line.strip()
|
||||||
|
#print(">" + line + "<")
|
||||||
|
|
||||||
|
args = line.split(" ")
|
||||||
|
args = [i for i in args if i]
|
||||||
|
if (len(args) == 0):
|
||||||
|
return
|
||||||
|
INS = args[0]
|
||||||
|
args = args[1:]
|
||||||
|
#print(args)
|
||||||
|
|
||||||
|
if (testArgIsLabel(INS, twoDotsIncluded=True)):
|
||||||
|
labels[INS[:-1]] = PC
|
||||||
|
return
|
||||||
|
|
||||||
|
instruction = None
|
||||||
|
try:
|
||||||
|
instruction = instructions[INS]
|
||||||
|
except:
|
||||||
|
print("ERROR : Bad instruction :", INS)
|
||||||
|
exit(1)
|
||||||
|
#print(instruction)
|
||||||
|
if (len(args) != len(instruction["args"])):
|
||||||
|
print(f"ERROR : Bad argument count. Excpected {len(instruction['args'])}, got {len(args)}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
return decodeInstruction(args, instruction)
|
||||||
|
|
||||||
|
|
||||||
|
def assemble(path):
|
||||||
|
PC = 0
|
||||||
|
assemble1st = []
|
||||||
|
with open(path, "r") as file:
|
||||||
|
# 1er lecture, pre-compilation
|
||||||
|
for line in file:
|
||||||
|
print(line, end="")
|
||||||
|
ret = decodeLine(line, PC)
|
||||||
|
if (ret != None):
|
||||||
|
assemble1st.append(ret)
|
||||||
|
if (not "DB" in ret):
|
||||||
|
PC += len(ret["opcode"])
|
||||||
|
print(" ==> ", ret)
|
||||||
|
print("\n\n\n\n\n\n")
|
||||||
|
print(assemble1st)
|
||||||
|
|
||||||
|
print("Labels : ", labels)
|
||||||
|
|
||||||
|
bytecode = []
|
||||||
|
for item in assemble1st:
|
||||||
|
if ("label" in item):
|
||||||
|
labelIndex = labels[item["label"]]
|
||||||
|
for index in range(len(item["opcode"])):
|
||||||
|
if (item["opcode"][index] == "label"):
|
||||||
|
item["opcode"][index] = labelIndex
|
||||||
|
bytecode.extend(item["opcode"])
|
||||||
|
pass
|
||||||
|
print("\n\n\n\n\n\n")
|
||||||
|
print(assemble1st)
|
||||||
|
print(bytecode)
|
||||||
|
|
||||||
|
|
||||||
|
if (__name__ == "__main__"):
|
||||||
|
path = ""
|
||||||
|
args = sys.argv
|
||||||
|
if (len(args) > 1):
|
||||||
|
path = args[1]
|
||||||
|
else:
|
||||||
|
print("NEED PATH !!!")
|
||||||
|
exit(0)
|
||||||
|
print(path)
|
||||||
|
|
||||||
|
|
||||||
|
assemble(path)
|
||||||
|
print("Labels :", labels)
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
#decodeLine(" MOV R4 R2 ; COMMENTAIRE OUAISSSSSSSSS", 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# print(instructions)
|
||||||
|
|
||||||
|
|
||||||
|
# ligne = "MOV R0 R1"
|
||||||
|
|
||||||
|
# ins = instructions["MOV"]
|
||||||
|
|
||||||
|
|
||||||
|
# print("\n\n\n")
|
||||||
|
# print(ins)
|
||||||
|
# print(ins["args"])
|
||||||
|
# print(ins["args"][0])
|
||||||
|
# print(ins["args"][1])
|
||||||
|
|
||||||
print(instructions)
|
|
||||||
20
notes.txt
20
notes.txt
@ -1,3 +1,23 @@
|
|||||||
|
DB : vvvv vvvv
|
||||||
|
CALL : 0000 0000 aaaa aaaa
|
||||||
|
RET : 1000 0000
|
||||||
|
JMP : 0100 0000 aaaa aaaa
|
||||||
|
JLT : 1100 0000 aaaa aaaa
|
||||||
|
JEQ : 0010 0000 aaaa aaaa
|
||||||
|
PUSH : 1010 00xx
|
||||||
|
POP : 0110 00xx
|
||||||
|
MOV v : 1110 00xx vvvv vvvv
|
||||||
|
SUB v : 0001 00xx vvvv vvvv
|
||||||
|
CMP v : 1001 00xx vvvv vvvv
|
||||||
|
MOV r : 0101 xxyy
|
||||||
|
SUB r : 1101 xxyy
|
||||||
|
CMP r : 0011 xxyy
|
||||||
|
LDR : 1011 xxyy aaaa aaaa
|
||||||
|
STR : 0111 xxyy aaaa aaaa
|
||||||
|
OUT : 1111 00xx
|
||||||
|
TIM : 1111 1000 mvvv vvvv
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
a = 0
|
a = 0
|
||||||
b = 1
|
b = 1
|
||||||
|
|||||||
BIN
programme.bin
Normal file
BIN
programme.bin
Normal file
Binary file not shown.
17
programme.py
Normal file
17
programme.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
program = bytes([
|
||||||
|
0b10100001, # PUSH R1
|
||||||
|
0b11100000, 0b00001111, # MOV R0, 15
|
||||||
|
0b11100001, 0b00000001, # MOV R1, 1
|
||||||
|
0b11010001, # SUB R0, R1
|
||||||
|
0b10010000, 0b00000000, # CMP R0, 0
|
||||||
|
0b00100000, 0b00001110, # JEQ 14
|
||||||
|
0b01000000, 0b00000101, # JMP 5
|
||||||
|
0b00000000, # DB 0
|
||||||
|
0b01000011, # 'C'
|
||||||
|
0b01100001, # POP R1
|
||||||
|
0b11100000, 0b01000001, # MOV R0, 'A'
|
||||||
|
0b10000000 # RET
|
||||||
|
])
|
||||||
|
|
||||||
|
with open("programme.bin", "wb") as f:
|
||||||
|
f.write(program)
|
||||||
11
test.py
Normal file
11
test.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
path = ""
|
||||||
|
args = sys.argv
|
||||||
|
if (len(args) > 1):
|
||||||
|
path = args[1]
|
||||||
|
else:
|
||||||
|
print("NEED PATH !!!")
|
||||||
|
exit(0)
|
||||||
|
print(path)
|
||||||
BIN
test_bin_epreuve3/call_label.bin
Normal file
BIN
test_bin_epreuve3/call_label.bin
Normal file
Binary file not shown.
1
test_bin_epreuve3/cmp_reg.bin
Normal file
1
test_bin_epreuve3/cmp_reg.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
0123456789:;<=>?
|
||||||
1
test_bin_epreuve3/cmp_val.bin
Normal file
1
test_bin_epreuve3/cmp_val.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
<EFBFBD>‘˙’a“z<E2809C>B‘X’0“9
|
||||||
BIN
test_bin_epreuve3/db1.bin
Normal file
BIN
test_bin_epreuve3/db1.bin
Normal file
Binary file not shown.
1
test_bin_epreuve3/db2.bin
Normal file
1
test_bin_epreuve3/db2.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
abcdefghijklmnopqrstuvwxyz
|
||||||
1
test_bin_epreuve3/db3.bin
Normal file
1
test_bin_epreuve3/db3.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||||
1
test_bin_epreuve3/db4.bin
Normal file
1
test_bin_epreuve3/db4.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
0123456789
|
||||||
BIN
test_bin_epreuve3/jeq_label.bin
Normal file
BIN
test_bin_epreuve3/jeq_label.bin
Normal file
Binary file not shown.
BIN
test_bin_epreuve3/jlt_label.bin
Normal file
BIN
test_bin_epreuve3/jlt_label.bin
Normal file
Binary file not shown.
BIN
test_bin_epreuve3/jmp_label.bin
Normal file
BIN
test_bin_epreuve3/jmp_label.bin
Normal file
Binary file not shown.
BIN
test_bin_epreuve3/ldr_label.bin
Normal file
BIN
test_bin_epreuve3/ldr_label.bin
Normal file
Binary file not shown.
1
test_bin_epreuve3/mov_reg.bin
Normal file
1
test_bin_epreuve3/mov_reg.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
PQRSTUVWXYZ[\]^_
|
||||||
1
test_bin_epreuve3/mov_val.bin
Normal file
1
test_bin_epreuve3/mov_val.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
<EFBFBD><01><><EFBFBD>a<EFBFBD>z<EFBFBD>B<EFBFBD>X<EFBFBD>0<EFBFBD>9
|
||||||
1
test_bin_epreuve3/out.bin
Normal file
1
test_bin_epreuve3/out.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
πρςσ
|
||||||
1
test_bin_epreuve3/pop.bin
Normal file
1
test_bin_epreuve3/pop.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
`abc
|
||||||
1
test_bin_epreuve3/push.bin
Normal file
1
test_bin_epreuve3/push.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
<EFBFBD>。「」
|
||||||
BIN
test_bin_epreuve3/str_label.bin
Normal file
BIN
test_bin_epreuve3/str_label.bin
Normal file
Binary file not shown.
1
test_bin_epreuve3/sub_reg.bin
Normal file
1
test_bin_epreuve3/sub_reg.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
ΠΡ<EFBFBD>ΣΤΥΦΧΨΩΪΫάέήί
|
||||||
1
test_bin_epreuve3/sub_val.bin
Normal file
1
test_bin_epreuve3/sub_val.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
˙azBX09
|
||||||
BIN
test_bin_epreuve3/tim.bin
Normal file
BIN
test_bin_epreuve3/tim.bin
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user