Java字节码是否有;间接跳转;?
如果我没有错的话,似乎所有的控制流都是Java中的字节码 像 还有一些是直接跳转指令 我的问题是,Java中是否有“间接跳转”指令 如果没有,我如何使用Java字节代码模拟Java中的“间接跳转”,就像在汇编中一样,我们可以这样做:Java字节码是否有;间接跳转;?,java,assembly,x86,bytecode,Java,Assembly,X86,Bytecode,如果我没有错的话,似乎所有的控制流都是Java中的字节码 像 还有一些是直接跳转指令 我的问题是,Java中是否有“间接跳转”指令 如果没有,我如何使用Java字节代码模拟Java中的“间接跳转”,就像在汇编中一样,我们可以这样做: goto address; // we can only know address at runtime 多谢各位 ------------------更新-------------------------- 基本上,我试图做的是在运行时更改我的控制流,但是 编
goto address; // we can only know address at runtime
多谢各位
------------------更新--------------------------
基本上,我试图做的是在运行时更改我的控制流,但是
编译时,控制流字节码的目标是硬编码的,这似乎是不可能的。根据您的定义,任何形式的方法调用都是“间接跳转”。根据您的定义,任何形式的方法调用都是“间接跳转”。编辑:完全错误地回答了这个问题。(见下文) JVM支持字节码级别的goto。您只需要像
原始答案,在源代码中的
goto
上:
最初有goto语句,但后来的版本没有。我认为可能的原因是,goto
是不必要的,可以用更可读的语句代替
goto关键字存在,但未实现
查看这段有趣的视频,编辑:完全错误地回答了这个问题。(见下文) JVM支持字节码级别的goto。您只需要像
原始答案,在源代码中的
goto
上:
最初有goto语句,但后来的版本没有。我认为可能的原因是,goto
是不必要的,可以用更可读的语句代替
goto关键字存在,但未实现
通过检查这段有趣的视频,间接跳转将使字节码验证器失败。阅读关于类文件是如何被验证的(在中),您将看到原因 特别是,以下情况无法核实:
- 所有控制流指令的目标必须是指令的开始(不能跳到指令的中间)
- 堆栈必须在特定指令上保持一致(相同的高度和值类型),无论VM如何到达该点
- 所有控制流指令的目标必须是指令的开始(不能跳到指令的中间)
- 堆栈必须在特定指令上保持一致(相同的高度和值类型),无论VM如何到达该点
- 间接跳转将使字节码验证器失败。阅读关于类文件是如何被验证的(在中),您将看到原因
特别是,以下情况无法核实:
goto
关键字。但是,它不允许使用它。@RohitJain:-是的,这是真的,但我认为现在它还没有实现。!我指的是你的第一句话。甚至更高版本也有。您仍然无法声明名为goto
的变量。但你甚至不能使用它。它从来没有,从来没有打算被实现,它的保留是为了表明这一点。我只看过一次这个有趣的视频:-它仍然有goto
关键字。但是,它不允许使用它。@RohitJain:-是的,这是真的,但我认为现在它还没有实现。!我指的是你的第一句话。甚至更高版本也有。您仍然无法声明名为goto
的变量。但你甚至不能使用它。它从来没有,从来没有打算被实现,它的保留是为了表明这一点。我只看过这段有趣的视频:-我想他指的是在运行时确定的地址,方法调用是JVM处理的跳转,尽管它不是定向的。谢谢,我更新了我的问题,我认为方法调用有一个明确的目标,比如“invokespecial#10”,你永远不能更改#10,对吗?@computereasy:你可以使用invokedynamic
生成一个调用,其目标可以在运行时更改。由于目标表示为MethodHandle
实例,因此invokedynamic
不仅可以(重新)定向到方法调用,还可以(重新)定向到简单的字段访问或对象构造等。此功能需要Java 7或更高版本。我想他指的是在运行时确定的地址,方法调用是JVM处理的一个跳转,尽管它不是定向的。谢谢,我更新了我的问题,方法调用有一个明确的目标,我认为,就像“invokespecial#10”,你永远不能更改#10,对吗?@computereasy:你可以使用invokedynamic
生成一个调用,其目标可以在运行时更改。由于目标表示为MethodHandle
实例,因此invokedynamic
不仅可以(重新)定向到方法调用,还可以(重新)定向到简单的字段访问或对象构造等。此功能需要Java 7或更高版本。查看op代码表,它看起来像lookupswitch
,tableswitch
,ret
,一些invoke
op代码将分支到需要在运行时计算的地址。但我不明白您想要实现什么:“在运行时更改我的控制流”?这就是如果陈述是为了什么。您试图解决的是什么问题,需要考虑像这样的指令级控制流问题?查看操作代码表,它看起来像查找开关
,表开关
,ret
,一些调用
操作代码将分支到需要在运行时计算的地址。但我不明白您想要实现什么:“在运行时更改我的控制流”?这就是如果陈述是为了什么。你想解决什么问题,你需要考虑像这样的指令级控制流问题?嗨,迈克,非常感谢你的回复!我不熟悉jvm相关的主题。。。那么你能给我这么多吗
goto address; // we can only know address at runtime