2016-03-21 13 views
2

私はJasminを使ってNOTゲートの動作を模倣しようとしています。JVMの論理NOT操作

  • がスタック
  • 整数が0の場合はオフ整数をポップ
  • 他のスタックに戻って1を押してスタック

I上に戻って0を押して、次のように動作がありますこれで2つの異なる試みを試みたが役に立たなかった。

試み1:もちろん

...(other code1) 
    ifeq 3   ; if the top of stack is 0, jump 3 lines down to "i_const1" 
    i_const0  ; top of stack was not 0, so we push 0 
    goto 2   ; jump 2 lines down to first line of (other code2) 
    i_const1 
    ...(other code2) 

そのオフセットとしてifeq <offset>がラベルではなく、ハードコードされた整数でかかるため、上記の例では動作しません。 ifeqと同様の操作がありますかは整数をパラメータとして受け入れますか?

試み2:

... 
    ifeq Zero  ; top of stack is 0, so jump to Zero 
    i_const0  ; top of stack was 1 or greater, so we push 0 
    ... 
    ... (some code in between) 
    ... 
    ifeq Zero  ; top of stack is 0, so jump to Zero 
    i_const0  ; top of stack was 1 or greater, so we push 0 
    ... 
    Zero: 
    i_const1  ; top of stack was 0, so push 1 to stack 
    goto <???>  ; How do I know which "ifeq Zero" called this label? 

これに伴う問題は、私は、NOT演算を利用して自分のコードで複数の場所をしたということです。私はラベル付きのifeqを使ってみましたが、終わったらgotoを使ってどの行に戻るべきかを知るにはどうすればいいですか?どのifeq Zeroがジャンプを行ったかを動的に判断する方法はありますか?

洞察力があれば幸いです。

+3

あなたの要件に応じて、値が0または1であることが分かっているなら 'x^1'を使うことができます。これはブランチやラベルを避けます。 –

+0

@Peter Lawrey:...または '1-x'。質問のコードのコメントは間違っていることに注意してください。値が正確に1または0であると予想される場合、ゼロでないことは、1またはそれ以上ではないことを意味するか、ゼロでないことも0より小さいことを意味する可能性があります。したがって、1または大きい "。いずれの場合も、「スタックの先頭は1以上でした」というのは間違っています... – Holger

答えて

4

整数をパラメータとして受け入れるifeqと同様の操作はありますか?

はい、$記号を使用して相対オフセットを指定できます。
しかし、相対オフセットは、行ではなくバイト数でカウントされます。

ifeq $+7  ; 0: jump +7 bytecodes forward from this instruction 
    iconst_0  ; +3 
    goto $+4  ; +4 
    iconst_1  ; +7 
    # ...  ; +8 

動的にジャンプをした「ゼロifeq」を決定する方法はありますか?

いいえ単一のZeroの代わりに複数の異なるラベルを使用します。

実際、動的リターンアドレスをサポートするバイトコード(jsr/ret)のペアがあります。しかし、これらのバイトコードはdeprecatedであり、Java 6+クラスのファイルではサポートされていません。