Epreuve 0 - rev 1
This commit is contained in:
parent
6ae130c794
commit
b3ca58576d
@ -13,7 +13,7 @@ _loop:
|
||||
MOV R0 R1 ; a = b
|
||||
MOV R1 R3 ; b = c
|
||||
|
||||
CMP R0 R1
|
||||
CMP R1 R0
|
||||
JLT _end ; end si b < a
|
||||
JMP _loop
|
||||
|
||||
|
||||
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 = {
|
||||
"DB" : {
|
||||
"ins": "DB",
|
||||
"args": [{
|
||||
"isRegister": False,
|
||||
"isValue": True,
|
||||
"isLabel": False
|
||||
"isLabel": False,
|
||||
}]
|
||||
},
|
||||
"CALL": {
|
||||
"ins": "CALL",
|
||||
"args": [{
|
||||
"isRegister": False,
|
||||
"isValue": False,
|
||||
@ -15,9 +18,11 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"RET": {
|
||||
"ins": "RET",
|
||||
"args": []
|
||||
},
|
||||
"JMP": {
|
||||
"ins": "JMP",
|
||||
"args": [{
|
||||
"isRegister": False,
|
||||
"isValue": False,
|
||||
@ -25,6 +30,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"JLT": {
|
||||
"ins": "JLT",
|
||||
"args": [{
|
||||
"isRegister": False,
|
||||
"isValue": False,
|
||||
@ -32,6 +38,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"JEQ": {
|
||||
"ins": "JEQ",
|
||||
"args": [{
|
||||
"isRegister": False,
|
||||
"isValue": False,
|
||||
@ -39,6 +46,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"PUSH": {
|
||||
"ins": "PUSH",
|
||||
"args": [{
|
||||
"isRegister": True,
|
||||
"isValue": False,
|
||||
@ -46,6 +54,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"POP": {
|
||||
"ins": "POP",
|
||||
"args": [{
|
||||
"isRegister": True,
|
||||
"isValue": False,
|
||||
@ -53,6 +62,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"MOV": {
|
||||
"ins": "MOV",
|
||||
"args": [{
|
||||
"isRegister": True,
|
||||
"isValue": False,
|
||||
@ -65,6 +75,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"SUB": {
|
||||
"ins": "SUB",
|
||||
"args": [{
|
||||
"isRegister": True,
|
||||
"isValue": False,
|
||||
@ -77,6 +88,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"CMP": {
|
||||
"ins": "CMP",
|
||||
"args": [{
|
||||
"isRegister": True,
|
||||
"isValue": False,
|
||||
@ -89,6 +101,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"LDR": {
|
||||
"ins": "LDR",
|
||||
"args": [{
|
||||
"isRegister": True,
|
||||
"isValue": False,
|
||||
@ -106,6 +119,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"STR": {
|
||||
"ins": "STR",
|
||||
"args": [{
|
||||
"isRegister": True,
|
||||
"isValue": False,
|
||||
@ -123,6 +137,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"OUT": {
|
||||
"ins": "OUT",
|
||||
"args": [{
|
||||
"isRegister": True,
|
||||
"isValue": False,
|
||||
@ -130,6 +145,7 @@ instructions = {
|
||||
}]
|
||||
},
|
||||
"TIM": {
|
||||
"ins": "TIM",
|
||||
"args": [{
|
||||
"isRegister": False,
|
||||
"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
|
||||
b = 1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user