汇编调用指令如何编译成机器代码? 标签会发生什么? 标签不再存在时,机器代码调用指令如何引用特定功能?
我知道编译后的代码中的标签已被函数的地址替换。
但是,仅在程序运行后,该功能的指令才会加载到ram存储器中。 那么内部的机器代码如何指示在编译之前通过标签指示的特定功能?
请以简单易懂的方式回答我,可能还附有实际示例。
答案 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上也可以使用绝对寻址和其他寻址方式。