MIPS 64 的 gcc 使用复杂的方法来定位和调用编译单元中不存在的函数。这个代码模型的名称是什么(以及它在哪里记录)?我搜索但没有发现它即将发布。它涉及$28
/$gp
和$25
/$t9
作为某种参数传递给被调用函数。
而且,这个翻译中是否存在错误(在代码生成或文本输出中)?
以下代码序列:
extern int g(int);
int f(int x)
{
return g(x) + 2;
}
生成此输出:
daddiu $sp,$sp,-16
sd $28,0($sp)
lui $28,%hi(%neg(%gp_rel(f(int))))
daddu $28,$28,$25 <--- sourcing $25/$t9
daddiu $28,$28,%lo(%neg(%gp_rel(f(int))))
ld $25,%call16(_Z1gi)($28)
sd $31,8($sp)
nop <--- where is the function call??
ld $31,8($sp)
ld $28,0($sp)
addiu $2,$2,2
j $31
daddiu $sp,$sp,16
在我上面的第二个 <-- 标记处,我希望看到一个间接函数调用,但所有的只有一个nop
(这可能是用于调用指令的延迟槽,否则无法解释)。
(在我的第一个标记处,它的来源是 25 美元,因此它必须是提供给的某种参数f
;f
似乎也设置了 25 美元g
。)
https://godbolt.org/z/11n9nxs63
添加-msym32
到上述命令行选项(告诉它假设所有符号都有一个 32 位地址),代码使用直接函数调用 via jal
。