Package: tdt4160
TDT4160 1.1.3tdt4160is an emulator for IJVM-microinstructions and pseudo-assembly, as
is commonly seen in theNTNU subject TDT4160,
particularly on its exams.There are two main components to this package.tdt4160.assemblyandtdt4160.ijvm.
Both function by letting you set registries, memory addresses and queue instructions
before executing them. During execution, each individual instruction is stepped through,
with lots of information printed so you can easily see what's going on. Technically
requires Python >= 3.7 to be conformant, but should probably work with any version >= 3.6.
There are no external dependencies besides the standard library.View on PyPI|Fork me on gitgudInstallationTo installtdt4160, run:$ python3 -m pip install tdt4160or to install from source:$ python3 setup.py installIntroductionDue to COVID-19, most NTNU classes switched from exams in exam halls with no
external help/tools allowed to home exams with all tools allowed. I thought it
would be pretty funny if you could just automate the exams now that you're
allowed to use tools.I was right, it was pretty funny.Example usagePseudo-assembly# This example from the Autumn 2020 exam, task 6fromtdt4160.assemblyimport*# First set the registries as specified in the taskset_asm_registries(R0=0xFFFF0000,R7=0xFFFF0001,R8=0xFFFF0002,R9=0xFFFF0003,)# Then set the memory addresses as specifiedset_asm_addresses({0xFFFF0000:0x00000001,0xFFFF0001:0x00000002,0xFFFF0002:0x00000003,0xFFFF0003:0x00000004,0xFFFF0004:0xFFFF0005})# Queue all the instructions to be performedassemble(0x0000FFFE,LOAD,R8,R0)assemble(0x0000FFFF,MOVC,R7,1)assemble(0x00010000,ADD,R0,R0,R7)assemble(0x00010001,LOAD,R9,R0)assemble(0x00010002,MUL,R9,R8,R9)assemble(0x00010003,ADD,R9,R9,R8)assemble(0x00010004,ADD,R0,R0,R7)assemble(0x00010005,LOAD,R8,R0)assemble(0x00010006,ADD,R8,R9,R8)# Then actually run themexecute_assembly(0x0000FFFE)# This function prints all the registries used in the task# In this case, we're looking for R8, which is 6print_asm_regs()This outputs the following:=============================== MEMORY: 0000FFFE ===============================
INSTRUCTION: LOAD R8=FFFF0002, R0=FFFF0000
Loaded value 00000001 into R8 from address FFFF0000
=============================== MEMORY: 0000FFFF ===============================
INSTRUCTION: MOVC R7=FFFF0001, Constant=00000001
Moved value 00000001 into R7
=============================== MEMORY: 00010000 ===============================
INSTRUCTION: ADD R0=FFFF0000, R0=FFFF0000, R7=00000001
Added R0=FFFF0000+R7=00000001
Result FFFF0001 stored in R0
=============================== MEMORY: 00010001 ===============================
INSTRUCTION: LOAD R9=FFFF0003, R0=FFFF0001
Loaded value 00000002 into R9 from address FFFF0001
=============================== MEMORY: 00010002 ===============================
INSTRUCTION: MUL R9=00000002, R8=00000001, R9=00000002
Multiplied R8=00000001*R9=00000002
Result 00000002 stored in R9
=============================== MEMORY: 00010003 ===============================
INSTRUCTION: ADD R9=00000002, R9=00000002, R8=00000001
Added R9=00000002+R8=00000001
Result 00000003 stored in R9
=============================== MEMORY: 00010004 ===============================
INSTRUCTION: ADD R0=FFFF0001, R0=FFFF0001, R7=00000001
Added R0=FFFF0001+R7=00000001
Result FFFF0002 stored in R0
=============================== MEMORY: 00010005 ===============================
INSTRUCTION: LOAD R8=00000001, R0=FFFF0002
Loaded value 00000003 into R8 from address FFFF0002
=============================== MEMORY: 00010006 ===============================
INSTRUCTION: ADD R8=00000003, R9=00000003, R8=00000003
Added R9=00000003+R8=00000003
Result 00000006 stored in R8
================================================================================
R0  = 0xFFFF0002
R7  = 0x00000001
R8  = 0x00000006
R9  = 0x00000003IJVM# This example from the Autumn 2020 exam, task 4fromtdt4160.ijvmimport*# Set the registries as specifiedset_ijvm_registries(SP=0x10101010,LV=0x30000000,CPP=0x10000001,TOS=0xFF000000,OPC=0xABCDE000,H=0x12345678,MAR=0xA5A5A5A5,MDR=0x5A5A5A5A,PC=0x55AA55AA)# Queue the microinstructions to runijvm(0b000001000,0b000001001,0b000,0b00010000,0b100000000,0b000,0b1111)ijvm(0b000001001,0b000001011,0b000,0b00111001,0b100000000,0b000,0b1100)ijvm(0b000001010,0b000010000,0b001,0b01011000,0b010101010,0b000,0b0001)ijvm(0b000001011,0b000001100,0b000,0b00111100,0b100000000,0b000,0b0101)ijvm(0b000001100,0b000000000,0b000,0b00111100,0b000010000,0b000,0b0101)ijvm(0b000001101,0b000001110,0b000,0b00110010,0b001000101,0b100,0b1000)# Actually run themexecute_ijvm(0b000001000)# Print the value of all the registries after execution# In this case, we're looking for several registries, so just check the ones you wantprint_all_ijvm()This outputs the following:======================= Instruction address: 0x000001000 =======================
next=0b000001001 JAM=0b000 ALU=0b00010000 C=0b100000000 Mem=0b000 B=0b1111
ALU is 0b010000, function: 0
Result of operation: 0x00000000
Final result: 0x00000000
C is 0b100000000
The following registries take the value of 0x00000000
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001001
======================= Instruction address: 0x000001001 =======================
next=0b000001011 JAM=0b000 ALU=0b00111001 C=0b100000000 Mem=0b000 B=0b1100
ALU is 0b111001, function: A + 1
A is always H=0x00000000
Result of operation: 0x00000001
Final result: 0x00000001
C is 0b100000000
The following registries take the value of 0x00000001
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001011
======================= Instruction address: 0x000001011 =======================
next=0b000001100 JAM=0b000 ALU=0b00111100 C=0b100000000 Mem=0b000 B=0b0101
ALU is 0b111100, function: A + B
A is always H=0x00000001
B is 0b0101 (5), yielding LV=0x30000000
Result of operation: 0x30000001
Final result: 0x30000001
C is 0b100000000
The following registries take the value of 0x30000001
H
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000001100
======================= Instruction address: 0x000001100 =======================
next=0b000000000 JAM=0b000 ALU=0b00111100 C=0b000010000 Mem=0b000 B=0b0101
ALU is 0b111100, function: A + B
A is always H=0x30000001
B is 0b0101 (5), yielding LV=0x30000000
Result of operation: 0x60000001
Final result: 0x60000001
C is 0b000010000
The following registries take the value of 0x60000001
LV
Mem is 0b000
Mem is 0, don't touch memory
Next instruction: 0b000000000
================================================================================
Next instruction is 0. We're done
SP = 0x10101010
LV = 0x60000001
CPP = 0x10000001
TOS = 0xFF000000
OPC = 0xABCDE000
H = 0x30000001
MAR = 0xA5A5A5A5
MDR = 0x5A5A5A5A
PC = 0x55AA55AA
MBR = 0xUNINITIALIZED
MBRU = 0xUNINITIALIZED
MPC = 0x00000000Note the uninitialized values were never touched, so they remain uninitialized.
That's okay as long as we don't use them after.På Norsktdt4160er en emulator for IJVM-mikronstruksjoner og pseudo-assemblykode,
som den man ofte ser iNTNU faget TDT4160sine eksamener.Det er to hoveddeler i pakkken.tdt4160.assemblyogtdt4160.ijvm.
Begge lar deg sette opp registre, minneaddresser, og sette instruksjoner i kø,
før de blir utført. Mens instruksjonene kjører printes det masse informasjon ut
om hva som faktisk utføres, slik at det blir lettere å se hva som skjer. Pakken
krever teknisk sett en Pythonversjon som er >= 3.7, men bør fungere fint med alt >= 3.6.
Pakken har ingen andre avhengigheter enn standardbiblioteket.Se på PyPI|Gafle meg på gitgudInstalleringFor å installeretdt4160, kjør:$ python3 -m pip install tdt4160eller for å installere fra kildekode:$ python3 setup.py installIntroduksjonPga. COVID-19 har de fleste fag på NTNU byttet fra eksamen i eksamenshaller
uten hjelpemidler til hjemmeeksamener med alle hjelpemidler tillat. Jeg
syntes det hadde vært litt morsomt hvis man bare hadde noe verktøy som
gjorde hele eksamenen for deg, nå som du kan bruke det du vil.Hadde rett, det var ganske morsomt.EksempelPseudo-assembly# Dette eksempelet er fra Høsteksamen 2020, oppgave 6fromtdt4160.assemblyimport*# Først, sett opp alle registre som det står i oppgavenset_asm_registries(R0=0xFFFF0000,R7=0xFFFF0001,R8=0xFFFF0002,R9=0xFFFF0003,)# Så sett opp alle minneaddresserset_asm_addresses({0xFFFF0000:0x00000001,0xFFFF0001:0x00000002,0xFFFF0002:0x00000003,0xFFFF0003:0x00000004,0xFFFF0004:0xFFFF0005})# Legg alle instruksjonene i kø for utførselassemble(0x0000FFFE,LOAD,R8,R0)assemble(0x0000FFFF,MOVC,R7,1)assemble(0x00010000,ADD,R0,R0,R7)assemble(0x00010001,LOAD,R9,R0)assemble(0x00010002,MUL,R9,R8,R9)assemble(0x00010003,ADD,R9,R9,R8)assemble(0x00010004,ADD,R0,R0,R7)assemble(0x00010005,LOAD,R8,R0)assemble(0x00010006,ADD,R8,R9,R8)# Kjør instruksjoneneexecute_assembly(0x0000FFFE)# Denne funksjonen printer alle registre som ble brukt i utførselen# I dette tilfellet ser vi etter R8, som bør være 6print_asm_regs()Koden spytter ut følgende:=============================== MEMORY: 0000FFFE ===============================
INSTRUCTION: LOAD R8=FFFF0002, R0=FFFF0000
Loaded value 00000001 into R8 from address FFFF0000
=============================== MEMORY: 0000FFFF ===============================
INSTRUCTION: MOVC R7=FFFF0001, Constant=00000001
Moved value 00000001 into R7
=============================== MEMORY: 00010000 ===============================
INSTRUCTION: ADD R0=FFFF0000, R0=FFFF0000, R7=00000001
Added R0=FFFF0000+R7=00000001
Result FFFF0001 stored in R0
=============================== MEMORY: 00010001 ===============================
INSTRUCTION: LOAD R9=FFFF0003, R0=FFFF0001
Loaded value 00000002 into R9 from address FFFF0001
=============================== MEMORY: 00010002 ===============================
INSTRUCTION: MUL R9=00000002, R8=00000001, R9=00000002
Multiplied R8=00000001*R9=00000002
Result 00000002 stored in R9
=============================== MEMORY: 00010003 ===============================
INSTRUCTION: ADD R9=00000002, R9=00000002, R8=00000001
Added R9=00000002+R8=00000001
Result 00000003 stored in R9
=============================== MEMORY: 00010004 ===============================
INSTRUCTION: ADD R0=FFFF0001, R0=FFFF0001, R7=00000001
Added R0=FFFF0001+R7=00000001
Result FFFF0002 stored in R0
=============================== MEMORY: 00010005 ===============================
INSTRUCTION: LOAD R8=00000001, R0=FFFF0002
Loaded value 00000003 into R8 from address FFFF0002
=============================== MEMORY: 00010006 ===============================
INSTRUCTION: ADD R8=00000003, R9=00000003, R8=00000003
Added R9=00000003+R8=00000003
Result 00000006 stored in R8
================================================================================
R0  = 0xFFFF0002
R7  = 0x00000001
R8  = 0x00000006
R9  = 0x00000003IJVM# Dette eksempelet er fra Høsteksamen 2020, oppgave 4fromtdt4160.ijvmimport*# Sett opp registre som det står i oppgavenset_ijvm_registries(SP=0x10101010,LV=0x30000000,CPP=0x10000001,TOS=0xFF000000,OPC=0xABCDE000,H=0x12345678,MAR=0xA5A5A5A5,MDR=0x5A5A5A5A,PC=0x55AA55AA)# Skriv inn alle mikronstruksjoneneijvm(0b000001000,0b000001001,0b000,0b00010000,0b100000000,0b000,0b1111)ijvm(0b000001001,0b000001011,0b000,0b00111001,0b100000000,0b000,0b1100)ijvm(0b000001010,0b000010000,0b001,0b01011000,0b010101010,0b000,0b0001)ijvm(0b000001011,0b000001100,0b000,0b00111100,0b100000000,0b000,0b0101)ijvm(0b000001100,0b000000000,0b000,0b00111100,0b000010000,0b000,0b0101)ijvm(0b000001101,0b000001110,0b000,0b00110010,0b001000101,0b100,0b1000)# Kjør instruksjoneneexecute_ijvm(0b000001000)# Skriv ut verdien til alle registrene etter at programmet har kjørt# I dette tilfellet ser vi etter flere registre, plukk ut de du vilprint_all_ijvm()Denne koden gir:=======================Instructionaddress:0x000001000=======================next=0b000001001JAM=0b000ALU=0b00010000C=0b100000000Mem=0b000B=0b1111ALUis0b010000,function:0Resultofoperation:0x00000000Finalresult:0x00000000Cis0b100000000Thefollowingregistriestakethevalueof0x00000000HMemis0b000Memis0,don't touch memoryNextinstruction:0b000001001=======================Instructionaddress:0x000001001=======================next=0b000001011JAM=0b000ALU=0b00111001C=0b100000000Mem=0b000B=0b1100ALUis0b111001,function:A+1AisalwaysH=0x00000000Resultofoperation:0x00000001Finalresult:0x00000001Cis0b100000000Thefollowingregistriestakethevalueof0x00000001HMemis0b000Memis0,don't touch memoryNextinstruction:0b000001011=======================Instructionaddress:0x000001011=======================next=0b000001100JAM=0b000ALU=0b00111100C=0b100000000Mem=0b000B=0b0101ALUis0b111100,function:A+BAisalwaysH=0x00000001Bis0b0101(5),yieldingLV=0x30000000Resultofoperation:0x30000001Finalresult:0x30000001Cis0b100000000Thefollowingregistriestakethevalueof0x30000001HMemis0b000Memis0,don't touch memoryNextinstruction:0b000001100=======================Instructionaddress:0x000001100=======================next=0b000000000JAM=0b000ALU=0b00111100C=0b000010000Mem=0b000B=0b0101ALUis0b111100,function:A+BAisalwaysH=0x30000001Bis0b0101(5),yieldingLV=0x30000000Resultofoperation:0x60000001Finalresult:0x60000001Cis0b000010000Thefollowingregistriestakethevalueof0x60000001LVMemis0b000Memis0,don't touch memoryNextinstruction:0b000000000================================================================================Nextinstructionis0.We're doneSP=0x10101010LV=0x60000001CPP=0x10000001TOS=0xFF000000OPC=0xABCDE000H=0x30000001MAR=0xA5A5A5A5MDR=0x5A5A5A5APC=0x55AA55AAMBR=0xUNINITIALIZEDMBRU=0xUNINITIALIZEDMPC=0x00000000Merk at to av registrene aldri ble satt, verken i oppsettet eller i koden, så
de er bareUNINITIALIZED. Det er greit så lenge de aldri brukes til noe.