2

I'm trying to mimic the behavior of a NOT gate using Jasmin. The behavior is as follows:

  • Pop an integer off the stack
  • if the integer is 0, push 1 back onto the stack
  • else push 0 back onto the stack

I've tried two different attempts at this but to no avail.

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

Of course, the above example doesn't work because ifeq <offset> takes in a Label rather than a hard-coded integer as its offset. Is there a similar operation to ifeq that does accept integers as a parameter?

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

The problem with this is that I've more than one place in my code making use of the NOT operation. I tried using ifeq with labels, but after I'm done how do I know which line to return to using goto? Is there a way to dynamically determine which "ifeq Zero" made the jump?

Any insight would be greatly appreciated.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Calseon
  • 325
  • 3
  • 18
  • 3
    depending on your requirement you could use `x ^ 1` if your know the values are 0 or 1. This avoid a branch or a label. – Peter Lawrey Mar 23 '16 at 08:24
  • @Peter Lawrey: …or `1 - x`. It should be noted that the comments in the question’s code are wrong. Either the value is expected to be exactly one or zero, then not being zero implies exactly one, not “1 or greater”, or not being not zero might also imply a smaller than zero value, so it’s not guaranteed to be “1 or greater”. In either case, “top of stack was 1 or greater” is wrong… – Holger Mar 30 '16 at 16:15

1 Answers1

4

Is there a similar operation to ifeq that does accept integers as a parameter?

Yes, you can specify relative offsets using $ sign.
BUT the relative offsets are counted in bytes, not in lines.

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

Is there a way to dynamically determine which "ifeq Zero" made the jump?

No. Use multiple different labels instead of single Zero.

Well, there is actually a pair of bytecodes (jsr/ret) that support dynamic return address. But these bytecodes are deprecated and are not supported in Java 6+ class files.

Community
  • 1
  • 1
apangin
  • 92,924
  • 10
  • 193
  • 247