Выполнение простой целочисленной операции в коде сборки 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 не печатает. Даже знак равенства не печатается. Любая помощь будет принята с благодарностью.

0 ответов

Другие вопросы по тегам