// fib.jas // // Author // Luc Charest // // Description // Reads the input for a number, then calculates Fibonnacci of that number // Illustrates how to invoke methods recursivly. // // Usage // To compile: java ijvmasm fib.jas // This will create fib.ijvm // // To run: java mic1sim mic1ijvm.mic1 fib.ijvm // Click the Run button // Enter the first number (up to 8 digit hex, using upper-case "A"-"F") // Press return // The result will be displayed // Repeat as often as desired // Click on the Stop button .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 a total .end-var start: BIPUSH 0x0 // initialize var a and b ISTORE a BIPUSH 0x20 // print " " OUT LDC_W OBJREF // prepare for method call INVOKEVIRTUAL getnum ISTORE a // store return value in a BIPUSH 0x3d // print "========" DUP DUP DUP DUP DUP DUP DUP OUT OUT OUT OUT OUT OUT OUT OUT BIPUSH 0xa // print new line OUT LDC_W OBJREF // prepare for method call ILOAD a INVOKEVIRTUAL fib // call fib (a) ISTORE total // add a and b, store in total LDC_W OBJREF // push OBJREF ILOAD total // push total, parameter for method print INVOKEVIRTUAL print GOTO start // start over .end-main .method fib( n ) // Fibonnacci function on the parameter n, called recursivly .var .end-var ILOAD n DUP // duplicate parameter n IFEQ fib0 // check if (n = 0), goto fib0 to return n, which is 0 directly DUP // duplicate parameter n BIPUSH 0x3 // check if (n < 3)... ISUB IFLT fib1 // goto fib1 to return 1 LDC_W OBJREF // prepare for method call ILOAD n // place n - 1 on top of stack BIPUSH 0x1 ISUB INVOKEVIRTUAL fib // call fib (n - 1), return value return on top of stack LDC_W OBJREF // prepare for method call ILOAD n // place n - 2 on top of stack BIPUSH 0x2 ISUB INVOKEVIRTUAL fib // call fib (n - 2), return value return on top of stack IADD // sum values returned by method call, place return value on top of stack fib0: IRETURN // return fib1: POP // remove parameter n from top of stack BIPUSH 0x1 // return 1 IRETURN .end-method .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 ) // print converts a number into a string of // characters and prints them. All of the characters // are pushed onto the stack, least significant // digit first, then popped off and printed. .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