1

I have been trying to write some Java bytecode and assemble it using Jasmin.

I am trying to get my head around subroutines, and am not sure why I obtain the following error message when running my program:

>java -jar jasmin.jar test.j
Generated: test.class

>java test
Exception in thread "main" java.lang.VerifyError: (class: test,
method: main signature: ([Ljava/lang/String;)V)
Cannot load return address from register 0
Could not find the main class: test. Program will exit.

Here's the bytecode in test.j:

.class public test
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 6
.limit locals 5

jsr a     ;Jump to subroutine 'a', pushing return address on operand stack
return    ;Exit the program

a:
astore_0  ;Store the return address in variable 0
aload_0   ;Save the address onto the stack as address will be overwritten in 'b'
jsr b     ;Jump to subroutine 'b', pushing return address on operand stack
astore_0  ;Store the address that was on the stack back into variable 0
ret 0     ;Return to just after "jsr a"

b:
astore_0  ;Store return address in variable 0
ret 0     ;Return to address stored in 0 (ie back to just after the jump in 'a')

.end method

I haven't had any problems with jumping to a single subroutine, but it seems as though something is going wrong when jumping to a subroutine from within a subroutine.

Any insight as to why this is failing would be much appreciated!

Jack
  • 2,153
  • 5
  • 28
  • 43
  • I don't know the internals of the JVM but on normal CPUs "register" $0 is always 0 and can't be set via assembler/bytecode. Are you sure that's possible in bytecode? – halfdan Dec 10 '11 at 11:16
  • I'm pretty sure it's fine to use "register" 0. I've tried the above program using 1 instead of 0 and I get the same error but for "register" 1. – Jack Dec 10 '11 at 11:36

1 Answers1

3

You can't load an address type value into any register, you can only store it and then ret instruction can retrieve it from there.

Java Virtual Machine Specification:

McDowell
  • 107,573
  • 31
  • 204
  • 267
Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
  • Thanks that must be the problem. Is there any way in that case to "save" the return address that we have for a, so that it does not get overwritten by b? – Jack Dec 10 '11 at 15:21
  • I see now that you can't use jsr and ret to make methods, as there are issues with stack size and the like - I'll define my methods "properly" with .method instead. – Jack Dec 11 '11 at 16:43