【问题标题】:Logical NOT operation in JVMJVM中的逻辑非操作
【发布时间】:2016-03-21 22:13:10
【问题描述】:

我正在尝试使用 Jasmin 模仿非门的行为。行为如下:

  • 从堆栈中弹出一个整数
  • 如果整数为0,则将1推回堆栈
  • 否则将 0 推回堆栈

我已经尝试了两种不同的尝试,但都无济于事。

尝试 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”进行了跳转?

任何见解将不胜感激。

【问题讨论】:

  • 根据您的要求,如果您知道值是 0 或 1,您可以使用 x ^ 1。这样可以避免分支或标签。
  • @Peter Lawrey:……或1 - x。需要注意的是问题代码中的cmets是错误的。要么该值应为 1 或 0,那么不为 0 意味着正好为 1,而不是“1 或更大”,或者不不为零也可能意味着小于零的值,因此不能保证为“1 或更大”。在任何一种情况下,“栈顶为 1 或更大”都是错误的……

标签: jvm bytecode jasmin


【解决方案1】:

是否有类似 ifeq 的操作接受整数作为参数?

是的,您可以使用$ 符号指定相对偏移量。
但是相对偏移量是按字节计算的,而不是按行计算的。

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

有没有办法动态确定是哪个“ifeq Zero”进行了跳转?

没有。使用多个不同的标签而不是单个 Zero

嗯,实际上有一对支持动态返回地址的字节码(jsr/ret)。但是这些字节码是deprecated,在 Java 6+ 类文件中不受支持。

【讨论】:

    猜你喜欢
    • 2017-08-12
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多