Epreuve 0 - rev 1

This commit is contained in:
Nogard 2026-03-21 18:41:03 +01:00
parent 6ae130c794
commit b3ca58576d
5 changed files with 349 additions and 4 deletions

View File

@ -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

Binary file not shown.

View File

@ -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)

View File

@ -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

11
test.py Normal file
View 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)