2011-12-10 3 views
1

Java 바이트 코드를 작성하고 Jasmin을 사용하여 어셈블하려고했습니다.Java 바이트 코드 서브 루틴 - 반송 주소를로드 할 수 없습니다.

나는 서브 루틴 주위에 내 머리를 얻으려고 노력하고, 내 프로그램 실행 때 다음과 같은 오류 메시지를 얻는 이유는 확실하지 오전 :

.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 
: 여기

>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. 

는 test.j의 바이트 코드의

단일 서브 루틴으로 점프하는 데 아무런 문제가 없었지만 서브 루틴 내에서 서브 루틴으로 점프 할 때 문제가있는 것처럼 보입니다.

왜 이것이 실패했는지에 대한 통찰력은 대단히 감사하겠습니다!

+0

나는 JVM의 내부를 알고 있지만 일반 CPU에서 "등록"$ 0은 항상 0이 아닌 수 없습니다 어셈블러/바이트 코드를 통해 설정 될 수 있습니다. 그게 바이트 코드에서 가능할까요? – halfdan

+0

"register"0을 사용하는 것이 좋습니다. 위의 프로그램을 0 대신 1을 사용하여 시도했지만 "register"1에 대해 동일한 오류가 발생했습니다. – Jack

+0

Ok, 그냥 추측이었습니다. – halfdan

답변

3

주소 유형 값을 어떤 레지스터에도로드 할 수 없으며, 레지스터 만 저장할 수 있고 ret 명령은 거기에서 검색 할 수 있습니다.

자바 가상 머신 사양 :

+0

감사합니다. 문제가되어야합니다. 이 경우 b에 의해 덮어 쓰이지 않도록 반송 주소를 "저장"하는 방법이 있습니까? – Jack

+0

스택 크기 등의 문제가 있기 때문에 jsr과 ret를 사용하여 메서드를 만들 수 없다는 것을 알았습니다. 대신에 메서드를 "적절하게".method로 정의 할 것입니다. – Jack