2016-03-21 11 views
2

Ich versuche, das Verhalten eines NOT-Gate mit Jasmin nachzuahmen. Das Verhalten ist wie folgt:Logische NOT-Operation in JVM

  • eine ganze Zahl vom Stapel Pop
  • , wenn die ganze Zahl 0 ist, drücken Sie 1 zurück auf den Stapel
  • sonst 0 zurückzudrängen auf den Stapel

I Ich habe zwei verschiedene Versuche versucht, aber ohne Erfolg.

Versuch 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) 

Natürlich ist das obige Beispiel nicht arbeiten, weil ifeq <offset> in einem Etikett nimmt eher als eine ganze Zahl hartcodiert als ausgeglichen. Gibt es eine ähnliche Operation wie ifeq, dass ganze Zahlen als Parameter akzeptiert?

Versuch 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? 

Das Problem dabei ist, dass ich mehr als einen Platz in meinem Code, der von der NICHT-Operation haben. Ich habe versucht, ifeq mit Labels zu verwenden, aber nachdem ich fertig bin, woher weiß ich, welche Zeile ich mit goto wiederherstellen soll? Gibt es eine Möglichkeit, dynamisch zu bestimmen, welcher "ifeq Zero" den Sprung gemacht hat?

Jeder Einblick würde sehr geschätzt werden.

+3

Je nach Anforderung können Sie 'x^1' verwenden, wenn Sie wissen, dass die Werte 0 oder 1 sind. Dies vermeidet eine Verzweigung oder ein Label. –

+0

@Peter Lawrey: ... oder '1 - x'. Es sollte beachtet werden, dass die Kommentare im Code der Frage falsch sind. Entweder erwartet man, dass der Wert genau eins oder null ist, dann bedeutet nicht Null genau eins, nicht "1 oder größer", oder nicht Null bedeutet möglicherweise auch einen Wert kleiner als Null, also ist es nicht garantiert "1 oder" größer ". In beiden Fällen war "Stapel oben war 1 oder größer" falsch ... – Holger

Antwort

4

Gibt es eine ähnliche Operation wie ifeq, die ganze Zahlen als Parameter akzeptiert?

Ja, Sie können relative Offsets unter Verwendung des $ Vorzeichens angeben.
ABER die relativen Offsets werden in Bytes gezählt, nicht in Zeilen.

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

Gibt es eine Möglichkeit dynamisch zu bestimmen, welche „ifeq Null“ den Sprung gemacht?

Nein. Verwenden Sie mehrere verschiedene Etiketten anstelle von einzelnen Zero.

Nun, es gibt tatsächlich ein Paar Bytecodes (jsr/ret), die dynamische Rücksprungadresse unterstützen. Aber diese Bytecodes sind deprecated und werden nicht in Java 6+ Klassendateien unterstützt.