编译器生成的相对地址以及它们在字节码(最好是java)中的表示方式?

编译器生成的相对地址以及它们在字节码(最好是java)中的表示方式?,java,memory-management,compiler-construction,bytecode,relative-addressing,Java,Memory Management,Compiler Construction,Bytecode,Relative Addressing,当在编译时无法进行地址绑定时,可以在加载/链接或运行时将相对(或者我们可以称之为可重定位地址)地址与实际物理地址关联起来。此外,在绑定物理地址之前,CPU还将这些相对地址转换为逻辑地址 从逻辑到物理的转换对我来说是一个已知的概念。但是,我对那些相对寻址感到困惑(AFAIK,他们称为相对寻址,因为编译器给它们赋值为相对于零)。我不确定(在字节码中)使用的是什么相对地址,或者它们是否真的需要,或者它们甚至与逻辑地址相同 Java字节码的抽象级别比本机代码高得多。根本没有内存地址的概念——方法是象征性

当在编译时无法进行地址绑定时,可以在加载/链接或运行时将相对(或者我们可以称之为可重定位地址)地址与实际物理地址关联起来。此外,在绑定物理地址之前,CPU还将这些相对地址转换为逻辑地址


从逻辑到物理的转换对我来说是一个已知的概念。但是,我对那些相对寻址感到困惑(AFAIK,他们称为相对寻址,因为编译器给它们赋值为相对于零)。我不确定(在字节码中)使用的是什么相对地址,或者它们是否真的需要,或者它们甚至与逻辑地址相同

Java字节码的抽象级别比本机代码高得多。根本没有内存地址的概念——方法是象征性的

考虑Java字节码最简单的方法是,它与Java语言的初始版本实际上是1:1。编译器做了一些事情,比如将局部变量转换为数字索引,将控制流转换为gotos,但在大多数情况下,它与原始代码非常相似


JVM负责在运行时将字节码解释或编译为本机代码。

在Java中获取对象的内存地址实际上是毫无意义的:因为JVM正在管理所有这些

换句话说:JVM将对象“放置”在任何适合它们的地方;甚至可以“移动”它们;例如,在垃圾收集期间


换句话说:作为一个Java程序员,你不在乎。如果你愿意;对此你无能为力。

你混淆了很多概念。相对地址就是需要将基址转换为绝对地址的地址。这种转变可以在很多方面发生。一种方法是在加载时转换它们,但它们也可能只是与CPU指令一起使用,CPU指令本质上支持相对寻址,在需要访问内存位置时正确计算

如果操作系统支持虚拟内存,那么普通进程中使用的所有地址都是逻辑地址,无论它们是相对引用的还是绝对引用的。从逻辑地址到物理地址的转换超出了应用程序的范围,并且独立于您在问题中提到的任何其他概念

类文件格式在内存位置方面不起作用

如果要在更高级别上应用术语“绝对”和“相对”,常量池索引是绝对的,因为它们不需要基本索引来标识实际索引。但是,当您想要在加载的文件中找到内存位置时,您不仅需要使用类文件加载到的地址,还必须将整个常量池解析为所需的项,因为常量池具有不同的字节大小。因此,项目通常根本不会被查找。取而代之的是,整个池在一次传递中被转换为具有恒定项大小的JVM特定表示,随后,JVM可能会查找该表的条目,而该表独立于类文件的内存位置

在字节码指令中,使用相对偏移量,这需要添加当前指令的位置以获得绝对位置,但请注意,这与问题中提到的概念不符。绝对位置仍然是指令序列中的位置,因此,在谈论地址时相对于代码的内存位置。此外,不使用相对偏移量,因为“在编译时不可能绑定”,生成的绝对位置在编译时已知。Java字节码指令集只是定义为使用相对偏移量来允许更紧凑的代码。从指令集的角度来看,我们可以说它本质上支持相对寻址。JVM如何实际实现其执行取决于JVM

因为,当JVM生成本机代码时,它知道代码的目标地址,并且可以根据需要自由决定使用相对地址或绝对地址


如前所述,上面描述的所有事情都发生在一个进程中,因此如果操作系统使用虚拟内存,那么所有这些都是操作系统可以调整的逻辑地址,例如通过MMU。这些概念是不相关的。

您通过引入可重新定位的概念,解决了这个问题。就我记忆所及,这是一个独立的概念,远远超出了你的理解范围。可能有两种类型的地址绑定。相对于逻辑,逻辑与相对。Ans有时相对地址和可重定位地址术语可以互换使用。这就是我为什么用这个词的原因。@BruceDavidWilner,但我同意你的观点。“可重定位更多”指的是尚未解析的地址(如果您是有意的话)。在JVM中,分支地址是PC相对的(即,分支指令位置的偏移量)。当然,当方法被jit时,这些相对地址根本没有任何物理意义。@SK logic我不确定它们在jit后是否立即绑定。地址不应该仍然是物理的(而是逻辑的)。依我看,它们应该由MMU映射,而不是JVM。谢谢。我实际上已经了解了JVM抽象和符号引用的概念。但我正试图更深入一点。首先,字节码中的相对地址到底是什么?例如,可以给出常量池引用(#3、#20等)或字节码数组索引(指令0:,2:4:)作为示例吗?其次,JVM执行引擎预先将字节码转换为本机/机器码。这些nativecode是直接可执行的还是应该被过滤掉