Выполнение простой целочисленной операции в коде сборки IJVM
Я вхожу в код сборки IJVM и сталкиваюсь с некоторыми странными проблемами. Я знаю, что IJVM - не самая популярная тема, но я надеялся, что кто-то сможет объяснить, что здесь происходит, и дать отзыв, если это возможно.
Моя цель - взять 5 шестнадцатеричных целочисленных значений и выполнить с ними следующую операцию: X + Y - Z + W - K
Мой код выглядит следующим образом:
// Description
// Program to input 5 hex numbers, and perform X+Y-Z+W-K
//
//
.constant
OBJREF 0x40 // needed for method invokation - see S.C.O. chapter 4
.end-constant
.main // start of program
.var // local variables for main program
x
y
z
w
k
total
total2
total3
total4
.end-var
start:
BIPUSH 0x0 // initialize vars
DUP
ISTORE x
ISTORE y
ISTORE z
ISTORE w
ISTORE k
OUT
LDC_W OBJREF
INVOKEVIRTUAL getnum
ISTORE x
BIPUSH 0x2b // print "+"
OUT
LDC_W OBJREF
INVOKEVIRTUAL getnum
ISTORE y
BIPUSH 0x2d // print "-"
OUT
LDC_W OBJREF
INVOKEVIRTUAL getnum
ISTORE z
BIPUSH 0x2b // print "+"
OUT
LDC_W OBJREF
INVOKEVIRTUAL getnum
ISTORE w
BIPUSH 0x2d // print "-"
OUT
LDC_W OBJREF
INVOKEVIRTUAL getnum
ISTORE k
BIPUSH 0x3d // print "="
BIPUSH 0xa
OUT
ILOAD x
ILOAD y
IADD
ISTORE total // x+y, store in total
LDC_W OBJREF // push OBJREF
ILOAD total // push total, parameter for method print
ILOAD z
ISUB
ISTORE total2 // result-z, store in total2
LDC_W OBJREF // push OBJREF
ILOAD total2
ILOAD w
IADD
ISTORE total3 // result+w, store in total3
LDC_W OBJREF // push OBJREF
ILOAD total3
ILOAD k
ISUB
ISTORE total4 // result-k, store in total4
LDC_W OBJREF // push OBJREF
BIPUSH 0x3d // print "="
ILOAD total4
INVOKEVIRTUAL print
.end-main
.method getnum()
.var
a
.end-var
BIPUSH 0x0 // initialize a
ISTORE a
geta: IN // read key press
DUP // duplicate key for comparison
BIPUSH 0xa // if key = cr,
IF_ICMPEQ return // return
DUP
BIPUSH 0x30 // if key < "0"
ISUB //
IFLT geta4 // goto geta4 (key is not a hex digit)
DUP
BIPUSH 0x3a // else if key < ":"
ISUB //
IFLT geta2 // goto geta2 (key is numeric character - "0"-"9")
DUP
BIPUSH 0x41 // else if key < "A"
ISUB //
IFLT geta4 // goto geta4 (key is not a hex digit)
DUP
BIPUSH 0x46 // else if key > "F"
SWAP //
ISUB //
IFLT geta4 // goto geta4 (key is not a hex digit)
DUP // else (key is letter - "A"-"F")
OUT // print key
BIPUSH 0x37 // convert key from character to number
ISUB //
GOTO geta3 // goto geta3
geta2: DUP
OUT // print key (numeric character)
BIPUSH 0x30 // convert key from character to number
ISUB
geta3: ILOAD a // shift a left 8 bits
DUP
IADD
DUP
IADD
DUP
IADD
DUP
IADD
IADD // add key to a
ISTORE a
GOTO geta // get next key
geta4: POP // pop invalid character
GOTO geta // get next key
return: OUT // print cr
ILOAD a // load a as return value
IRETURN // return
.end-method
.method print( total )
.var
place
index
.end-var
print: BIPUSH 0x9 // there are 8 nibbles in each integer--setting
// this as nine pushes 10 characters onto the
// stack, thus a total of ten printed digits,
// but setting this less does not remove the
// two leading zeros, just removes significant
// digits
ISTORE index
BIPUSH 0x1 // comparison bit
ISTORE place
print1: BIPUSH 0x0
ILOAD index // index = index - 1
BIPUSH 0x1
ISUB
DUP
IFEQ pall // if index = 0 goto pall
ISTORE index
ILOAD total // else
ILOAD place //
IAND // if 1st bit of current nibble is zero (total & place)
IFEQ print2 // goto print2
BIPUSH 0x1 // else set first bit of character
IADD
print2: ILOAD place // place = place << 1
DUP
IADD
ISTORE place
ILOAD total
ILOAD place
IAND // if 2nd bit of current nibble is zero (total & place)
IFEQ print3 // goto print3
BIPUSH 0x2 // else set second bit of character
IADD
print3: ILOAD place // place = place << 1
DUP
IADD
ISTORE place
ILOAD total
ILOAD place
IAND // if 3rd bit of current nibble is zero (total & place)
IFEQ print4 // goto print4
BIPUSH 0x4 // else set second bit of character
IADD
print4: ILOAD place // place = place << 1
DUP
IADD
ISTORE place
ILOAD total
ILOAD place
IAND // if 4th bit of current nibble is zero (total & place)
IFEQ print5 // goto print5
BIPUSH 0x8 // else set second bit of character
IADD
print5: ILOAD place // place = place << 1
DUP
IADD
ISTORE place
GOTO print1
pall: POP // Pop off leading 0's
POP
BIPUSH 0x9
ISTORE index
pall1: ILOAD index // index = index - 1
BIPUSH 0x1
ISUB
DUP
IFEQ return // if index = 0 return
ISTORE index
DUP
BIPUSH 0xa // else if character < 0xa goto pall1
ISUB
IFLT pall2
BIPUSH 0x37 // else convert character to "A"-"F"
IADD
OUT // print character
GOTO pall1 // goto pall (prepare & print next character)
pall2: BIPUSH 0x30 // convert character to "0"-"9"
IADD
OUT // print character
GOTO pall1 // goto pall1 (prepare & print next character)
return: BIPUSH 0xa // print cr
OUT
IRETURN // no return value
.end-method
Безопасно просто взглянуть на основной метод, так как print и getnum - это методы, используемые другими людьми, и я могу быть уверен, что они работают как задумано.
Программа, кажется, просто повторяет вводы, но никогда не дает полного значения в конце. Это выглядит так для входов 2, 3, 6, 7, 4
2
+3
-6
+7
-4
Это те операции, которые он должен делать, но я не могу понять, почему total4 не печатает. Даже знак равенства не печатается. Любая помощь будет принята с благодарностью.