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



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

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

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

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

类文件格式不根据内存位置进行操作。

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

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

既然您提到了JVM的本机代码生成,那么当JVM生成本机代码时,它知道代码的目标地址,并且可以自由地决定使用相对地址或绝对地址,只要它适合。

正如已经提到的,上面所描述的一切都发生在一个进程中,所以如果操作系统使用虚拟内存,那么这一切都是在逻辑地址方面进行的,操作系统可以通过逻辑地址进行调整,例如通过MMU。

Java字节码在比本机机器码更高的抽象级别上运行。根本没有内存地址的概念——方法是用符号表示的。

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

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

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

换句话说:JVM把对象"放在"它应该放在的地方;它们甚至可以被"移动";例如在垃圾收集期间。

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

最新更新