diff --git a/Epreuve0.asm b/Epreuve0.asm index fcd83f2..282e8e8 100644 --- a/Epreuve0.asm +++ b/Epreuve0.asm @@ -13,9 +13,9 @@ _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 _end: - RET + RET \ No newline at end of file diff --git a/__pycache__/assembleur.cpython-314.pyc b/__pycache__/assembleur.cpython-314.pyc new file mode 100644 index 0000000..ba38b91 Binary files /dev/null and b/__pycache__/assembleur.cpython-314.pyc differ diff --git a/assembleur.py b/assembleur.py index 7c3b901..932b8e0 100644 --- a/assembleur.py +++ b/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) \ No newline at end of file diff --git a/notes.txt b/notes.txt index 17d93d8..1ac8d6a 100644 --- a/notes.txt +++ b/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 diff --git a/test.py b/test.py new file mode 100644 index 0000000..4b49ee5 --- /dev/null +++ b/test.py @@ -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)