Hw9: done 2 and 3 (without explaination)
This commit is contained in:
parent
bae4fb3f26
commit
c80229f595
4 changed files with 293 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,6 @@
|
|||
*.ijvm
|
||||
*.mic1
|
||||
|
||||
# ---> TeX
|
||||
## Core latex/pdflatex auxiliary files:
|
||||
*.aux
|
||||
|
|
22
Homework 9/ex2.jas
Normal file
22
Homework 9/ex2.jas
Normal file
|
@ -0,0 +1,22 @@
|
|||
.constant
|
||||
OBJREF 0x40
|
||||
.end-constant
|
||||
|
||||
.main
|
||||
LDC_W OBJREF
|
||||
IN
|
||||
INVOKEVIRTUAL even
|
||||
HALT
|
||||
.end-main
|
||||
|
||||
.method even(x)
|
||||
.var
|
||||
.end-var
|
||||
ILOAD x
|
||||
JIFEVEN even
|
||||
BIPUSH 0x00
|
||||
IRETURN // odd
|
||||
even:
|
||||
BIPUSH 0x01
|
||||
IRETURN // even
|
||||
.end-method
|
26
Homework 9/ijvm.conf
Normal file
26
Homework 9/ijvm.conf
Normal file
|
@ -0,0 +1,26 @@
|
|||
// configuration file for IJVM Assembler
|
||||
0x10 BIPUSH byte // Push byte onto stack
|
||||
0x59 DUP // Copy top word on stack; push onto stack
|
||||
0xA7 GOTO label // Unconditional jump
|
||||
0x60 IADD // Pop two words from stack; push their sum
|
||||
0x7E IAND // Pop two words from stack; push Boolean AND
|
||||
0x99 IFEQ label // Pop word from stack; branch if it is zero
|
||||
0x9B IFLT label // Pop word from stack; branch if it is less than zero
|
||||
0x9F IF_ICMPEQ label // Pop two words from stack; branch if equal
|
||||
0x84 IINC varnum const // Add a constant to a local variable
|
||||
0x15 ILOAD varnum // Push local variable onto stack
|
||||
0xB6 INVOKEVIRTUAL offset // Invoke a method
|
||||
0xB0 IOR // Pop two words from stack; push Boolean OR
|
||||
0xAC IRETURN // Return from method with integer value
|
||||
0x36 ISTORE varnum // Pop word from stack; store in local variable
|
||||
0x64 ISUB // Pop two words from stack; push their difference
|
||||
0x13 LDC_W index // Push constant from constant pool onto stack
|
||||
0x00 NOP // Do nothing
|
||||
0x57 POP // Delete word on top of stack
|
||||
0x5F SWAP // Swap the two top words on the stack
|
||||
0xC4 WIDE // Prefix instruction; next instruction has 16-bit index
|
||||
0xFF HALT // halt the simulator
|
||||
0xFE ERR // print ERROR and halt
|
||||
0xFD OUT // Pop a word from the stack and use the low order 8-bits as an ASCI character to display on screen
|
||||
0xFC IN // Read a character from standard input and put it in the low order 8-bits of a word pushed onto the stack
|
||||
0x42 JIFEVEN label
|
242
Homework 9/mic1ijvm.mal
Normal file
242
Homework 9/mic1ijvm.mal
Normal file
|
@ -0,0 +1,242 @@
|
|||
// note that this is nearly identical to the example
|
||||
// given in Tanenbaum. Note:
|
||||
//
|
||||
// 1) SlashSlash-style ("//") comment characters have been added.
|
||||
//
|
||||
// 2) "nop" has been added as a pseudo-instruction to indicate that
|
||||
// nothing should be done except goto the next instruction. It
|
||||
// is a do-nothing sub-instruction that allows us to have MAL
|
||||
// statements without a label.
|
||||
//
|
||||
// 3) instructions are "anchored" to locations in the control
|
||||
// store as defined below with the ".label" pseudo-instruction
|
||||
//
|
||||
// 4) a default instruction may be specified using the ".default"
|
||||
// pseudo-instruction. This instruction is placed in all
|
||||
// unused locations of the control store by the mic1 MAL assembler.
|
||||
//
|
||||
|
||||
// labeled statements are "anchored" at the specified control store address
|
||||
.label nop1 0x00
|
||||
.label bipush1 0x10
|
||||
.label ldc_w1 0x13
|
||||
.label iload1 0x15
|
||||
.label wide_iload1 0x115
|
||||
.label istore1 0x36
|
||||
.label wide_istore1 0x136
|
||||
.label pop1 0x57
|
||||
.label dup1 0x59
|
||||
.label swap1 0x5F
|
||||
.label iadd1 0x60
|
||||
.label isub1 0x64
|
||||
.label iand1 0x7E
|
||||
.label iinc1 0x84
|
||||
.label ifeq1 0x99
|
||||
.label iflt1 0x9B
|
||||
.label if_icmpeq1 0x9F
|
||||
.label goto1 0xA7
|
||||
.label ireturn1 0xAC
|
||||
.label ior1 0xB0
|
||||
.label invokevirtual1 0xB6
|
||||
.label wide1 0xC4
|
||||
.label halt1 0xFF
|
||||
.label err1 0xFE
|
||||
.label out1 0xFD
|
||||
.label in1 0xFC
|
||||
.label jifeven1 0x42
|
||||
|
||||
// default instruction to place in any unused addresses of the control store
|
||||
.default goto err1
|
||||
|
||||
Main1 PC = PC + 1; fetch; goto (MBR) // MBR holds opcode; get next byte; dispatch
|
||||
|
||||
nop1 goto Main1 // Do nothing
|
||||
|
||||
iadd1 MAR = SP = SP - 1; rd // Read in next-to-top word on stack
|
||||
iadd2 H = TOS // H = top of stack
|
||||
iadd3 MDR = TOS = MDR + H; wr; goto Main1 // Add top two words; write to top of stack
|
||||
|
||||
isub1 MAR = SP = SP - 1; rd // Read in next-to-top word on stack
|
||||
isub2 H = TOS // H = top of stack
|
||||
isub3 MDR = TOS = MDR - H; wr; goto Main1 // Do subtraction; write to top of stack
|
||||
|
||||
iand1 MAR = SP = SP - 1; rd // Read in next-to-top word on stack
|
||||
iand2 H = TOS // H = top of stack
|
||||
iand3 MDR = TOS = MDR AND H; wr; goto Main1 // Do AND; write to new top of stack
|
||||
|
||||
ior1 MAR = SP = SP - 1; rd // Read in next-to-top word on stack
|
||||
ior2 H = TOS // H = top of stack
|
||||
ior3 MDR = TOS = MDR OR H; wr; goto Main1 // Do OR; write to new top of stack
|
||||
|
||||
dup1 MAR = SP = SP + 1 // Increment SP and copy to MAR
|
||||
dup2 MDR = TOS; wr; goto Main1 // Write new stack word
|
||||
|
||||
pop1 MAR = SP = SP - 1; rd // Read in next-to-top word on stack
|
||||
pop2 // Wait for new TOS to be read from memory
|
||||
pop3 TOS = MDR; goto Main1 // Copy new word to TOS
|
||||
|
||||
swap1 MAR = SP - 1; rd // Set MAR to SP - 1; read 2nd word from stack
|
||||
swap2 MAR = SP // Set MAR to top word
|
||||
swap3 H = MDR; wr // Save TOS in H; write 2nd word to top of stack
|
||||
swap4 MDR = TOS // Copy old TOS to MDR
|
||||
swap5 MAR = SP - 1; wr // Set MAR to SP - 1; write as 2nd word on stack
|
||||
swap6 TOS = H; goto Main1 // Update TOS
|
||||
|
||||
bipush1 SP = MAR = SP + 1 // MBR = the byte to push onto stack
|
||||
bipush2 PC = PC + 1; fetch // Increment PC, fetch next opcode
|
||||
bipush3 MDR = TOS = MBR; wr; goto Main1 // Sign-extend constant and push on stack
|
||||
|
||||
|
||||
iload1 H = LV // MBR contains index; copy LV to H
|
||||
iload2 MAR = MBRU + H; rd // MAR = address of local variable to push
|
||||
iload3 MAR = SP = SP + 1 // SP points to new top of stack; prepare write
|
||||
iload4 PC = PC + 1; fetch; wr // Inc PC; get next opcode; write top of stack
|
||||
iload5 TOS = MDR; goto Main1 // Update TOS
|
||||
|
||||
istore1 H = LV // MBR contains index; Copy LV to H
|
||||
istore2 MAR = MBRU + H // MAR = address of local variable to store into
|
||||
istore3 MDR = TOS; wr // Copy TOS to MDR; write word
|
||||
istore4 SP = MAR = SP - 1; rd // Read in next-to-top word on stack
|
||||
istore5 PC = PC + 1; fetch // Increment PC; fetch next opcode
|
||||
istore6 TOS = MDR; goto Main1 // Update TOS
|
||||
wide1 PC = PC + 1; fetch; goto (MBR OR 0x100) // Multiway branch with high bit set
|
||||
|
||||
wide_iload1 PC = PC + 1; fetch // MBR contains 1st index byte; fetch 2nd
|
||||
wide_iload2 H = MBRU << 8 // H = 1st index byte shifted left 8 bits
|
||||
wide_iload3 H = MBRU OR H // H = 16-bit index of local variable
|
||||
wide_iload4 MAR = LV + H; rd; goto iload3 // MAR = address of local variable to push
|
||||
|
||||
wide_istore1 PC = PC + 1; fetch // MBR contains 1st index byte; fetch 2nd
|
||||
wide_istore2 H = MBRU << 8 // H = 1st index byte shifted left 8 bits
|
||||
wide_istore3 H = MBRU OR H // H = 16-bit index of local variable
|
||||
wide_istore4 MAR = LV + H; goto istore3 // MAR = address of local variable to store into
|
||||
|
||||
ldc_w1 PC = PC + 1; fetch // MBR contains 1st index byte; fetch 2nd
|
||||
ldc_w2 H = MBRU << 8 // H = 1st index byte << 8
|
||||
ldc_w3 H = MBRU OR H // H = 16-bit index into constant pool
|
||||
ldc_w4 MAR = H + CPP; rd; goto iload3 // MAR = address of constant in pool
|
||||
|
||||
iinc1 H = LV // MBR contains index; Copy LV to H
|
||||
iinc2 MAR = MBRU + H; rd // Copy LV + index to MAR; Read variable
|
||||
iinc3 PC = PC + 1; fetch // Fetch constant
|
||||
iinc4 H = MDR // Copy variable to H
|
||||
iinc5 PC = PC + 1; fetch // Fetch next opcode
|
||||
iinc6 MDR = MBR + H; wr; goto Main1 // Put sum in MDR; update variable
|
||||
|
||||
goto1 OPC = PC - 1 // Save address of opcode.
|
||||
goto2 PC = PC + 1; fetch // MBR = 1st byte of offset; fetch 2nd byte
|
||||
goto3 H = MBR << 8 // Shift and save signed first byte in H
|
||||
goto4 H = MBRU OR H // H = 16-bit branch offset
|
||||
goto5 PC = OPC + H; fetch // Add offset to OPC
|
||||
goto6 goto Main1 // Wait for fetch of next opcode
|
||||
|
||||
iflt1 MAR = SP = SP - 1; rd // Read in next-to-top word on stack
|
||||
iflt2 OPC = TOS // Save TOS in OPC temporarily
|
||||
iflt3 TOS = MDR // Put new top of stack in TOS
|
||||
iflt4 N = OPC; if (N) goto T; else goto F // Branch on N bit
|
||||
|
||||
ifeq1 MAR = SP = SP - 1; rd // Read in next-to-top word of stack
|
||||
ifeq2 OPC = TOS // Save TOS in OPC temporarily
|
||||
ifeq3 TOS = MDR // Put new top of stack in TOS
|
||||
ifeq4 Z = OPC; if (Z) goto T; else goto F // Branch on Z bit
|
||||
|
||||
if_icmpeq1 MAR = SP = SP - 1; rd // Read in next-to-top word of stack
|
||||
if_icmpeq2 MAR = SP = SP - 1 // Set MAR to read in new top-of-stack
|
||||
if_icmpeq3 H = MDR; rd // Copy second stack word to H
|
||||
if_icmpeq4 OPC = TOS // Save TOS in OPC temporarily
|
||||
if_icmpeq5 TOS = MDR // Put new top of stack in TOS
|
||||
if_icmpeq6 Z = OPC - H; if (Z) goto T; else goto F // If top 2 words are equal, goto T, else goto F
|
||||
|
||||
T OPC = PC - 1; fetch; goto goto2 // Same as goto1; needed for target address
|
||||
|
||||
F PC = PC + 1 // Skip first offset byte
|
||||
F2 PC = PC + 1; fetch // PC now points to next opcode
|
||||
F3 goto Main1 // Wait for fetch of opcode
|
||||
|
||||
invokevirtual1 PC = PC + 1; fetch // MBR = index byte 1; inc. PC, get 2nd byte
|
||||
invokevirtual2 H = MBRU << 8 // Shift and save first byte in H
|
||||
invokevirtual3 H = MBRU OR H // H = offset of method pointer from CPP
|
||||
invokevirtual4 MAR = CPP + H; rd // Get pointer to method from CPP area
|
||||
invokevirtual5 OPC = PC + 1 // Save Return PC in OPC temporarily
|
||||
invokevirtual6 PC = MDR; fetch // PC points to new method; get param count
|
||||
invokevirtual7 PC = PC + 1; fetch // Fetch 2nd byte of parameter count
|
||||
invokevirtual8 H = MBRU << 8 // Shift and save first byte in H
|
||||
invokevirtual9 H = MBRU OR H // H = number of parameters
|
||||
invokevirtual10 PC = PC + 1; fetch // Fetch first byte of # locals
|
||||
invokevirtual11 TOS = SP - H // TOS = address of OBJREF - 1
|
||||
invokevirtual12 TOS = MAR = TOS + 1 // TOS = address of OBJREF (new LV)
|
||||
invokevirtual13 PC = PC + 1; fetch // Fetch second byte of # locals
|
||||
invokevirtual14 H = MBRU << 8 // Shift and save first byte in H
|
||||
invokevirtual15 H = MBRU OR H // H = # locals
|
||||
invokevirtual16 MDR = SP + H + 1; wr // Overwrite OBJREF with link pointer
|
||||
invokevirtual17 MAR = SP = MDR; // Set SP, MAR to location to hold old PC
|
||||
invokevirtual18 MDR = OPC; wr // Save old PC above the local variables
|
||||
invokevirtual19 MAR = SP = SP + 1 // SP points to location to hold old LV
|
||||
invokevirtual20 MDR = LV; wr // Save old LV above saved PC
|
||||
invokevirtual21 PC = PC + 1; fetch // Fetch first opcode of new method.
|
||||
invokevirtual22 LV = TOS; goto Main1 // Set LV to point to LV Frame
|
||||
|
||||
ireturn1 MAR = SP = LV; rd // Reset SP, MAR to get link pointer
|
||||
ireturn2 // Wait for read
|
||||
ireturn3 LV = MAR = MDR; rd // Set LV to link ptr; get old PC
|
||||
ireturn4 MAR = LV + 1 // Set MAR to read old LV
|
||||
ireturn5 PC = MDR; rd; fetch // Restore PC; fetch next opcode
|
||||
ireturn6 MAR = SP // Set MAR to write TOS
|
||||
ireturn7 LV = MDR // Restore LV
|
||||
ireturn8 MDR = TOS; wr; goto Main1 // Save return value on original top of stack
|
||||
|
||||
halt1 goto halt1
|
||||
|
||||
err1 OPC=H=-1
|
||||
OPC=H+OPC
|
||||
MAR=H+OPC // compute IO address
|
||||
OPC=H=1 // 1
|
||||
OPC=H=H+OPC // 10
|
||||
OPC=H=H+OPC // 100
|
||||
OPC=H=H+OPC // 1000
|
||||
OPC=H=H+OPC+1 // 10001
|
||||
OPC=H=H+OPC // 100010
|
||||
MDR=H+OPC+1;wr // 1000101 'E'
|
||||
OPC=H=1 // 1
|
||||
OPC=H=H+OPC // 10
|
||||
OPC=H=H+OPC+1 // 101
|
||||
OPC=H=H+OPC // 1010
|
||||
OPC=H=H+OPC // 10100
|
||||
OPC=H=H+OPC+1 // 101001
|
||||
MDR=H+OPC;wr // 1010010 'R'
|
||||
nop
|
||||
MDR=H+OPC;wr // 1010010 'R'
|
||||
OPC=H=1 // 1
|
||||
OPC=H=H+OPC // 10
|
||||
OPC=H=H+OPC // 100
|
||||
OPC=H=H+OPC+1 // 1001
|
||||
OPC=H=H+OPC+1 // 10011
|
||||
OPC=H=H+OPC+1 // 100111
|
||||
MDR=H+OPC+1;wr // 1001111 'O'
|
||||
OPC=H=1 // 1
|
||||
OPC=H=H+OPC // 10
|
||||
OPC=H=H+OPC+1 // 101
|
||||
OPC=H=H+OPC // 1010
|
||||
OPC=H=H+OPC // 10100
|
||||
OPC=H=H+OPC+1 // 101001
|
||||
MDR=H+OPC;wr // 1010010 'R'
|
||||
goto halt1
|
||||
|
||||
out1 OPC=H=-1
|
||||
OPC=H+OPC
|
||||
MAR=H+OPC // compute OUT address
|
||||
MDR=TOS; wr // write to output
|
||||
nop
|
||||
MAR=SP=SP-1; rd // decrement stack pointer
|
||||
nop
|
||||
TOS=MDR; goto Main1
|
||||
|
||||
in1 OPC=H=-1
|
||||
OPC=H+OPC
|
||||
MAR=H+OPC;rd // compute IN address ; read from input
|
||||
MAR=SP=SP+1 // increment SP; wait for read
|
||||
TOS=MDR;wr ; goto Main1 // Write
|
||||
|
||||
jifeven1 H = 1
|
||||
jifeven2 Z = TOS AND H; if (Z) goto T; else goto F
|
||||
|
Reference in a new issue