调用说明:编译成机器代码

时间:2019-12-22 19:25:10

标签: assembly machine-code

汇编调用指令如何编译成机器代码? 标签会发生什么? 标签不再存在时,机器代码调用指令如何引用特定功能?

我知道编译后的代码中的标签已被函数的地址替换。

但是,仅在程序运行后,该功能的指令才会加载到ram存储器中。 那么内部的机器代码如何指示在编译之前通过标签指示的特定功能?

请以简单易懂的方式回答我,可能还附有实际示例。

1 个答案:

答案 0 :(得分:2)

汇编语言标签是编译时的汇编时和链接时的构造—在汇编和/或链接期间,为这些标签提供了一个内存地址,有时是绝对地址,但从一开始就经常是相对地址。标签所在部分的

在机器代码中省略了标签(以及从符号/标签名称到地址或偏移量的映射)-当今的处理器不了解或看不到机器代码中的汇编标签。

在汇编语言中,调用指令以及if-then,while等的分支指令将分支目标作为其操作数之一。对于大多数这些指令,在机器代码中,操作数被编码为pc相对偏移量,并作为机器代码指令的操作数存储在立即数字段中。

请参见pc-relative addressing mode

立即数的pc相对偏移量由硬件使用类似于指令地址+立即数的公式恢复为绝对地址:

pc 下一周期:= pc 当前分支指令 +立即*比例+偏差。

 CPU   Scale    Bias
 -------------------
 x86      1       0
 MIPS     4       4
 RISC V   2       0

然后,汇编器/链接器使用相同的公式,尽管可以立即解决,但实际上可以逆转此计算:

offset =(label target -pc current-branch-instruction -Bias)/比例

然后将此偏移量编码在分支或调用指令的立即数字段中。


例如,在MIPS处理器上,分支指令具有16位立即数字段,用于保存此类偏移量。立即值-1将分支到self,立即值-5将向后分支4条指令,而立即值+5将向后分支6条指令。

MIPS调用指令使用绝对地址而不是pc相对地址,因此它们被编码为大立即数,其文本段的相对偏移长度为26位。 (该计算不会求和pc的低26位,因此,它并不是真正的pc相对寻址。)

在RISC V和x86上,可以使用相对于pc的寻址来完成分支指令和调用指令,尽管在x86上也可以使用绝对寻址和其他寻址方式。