作为此问题的扩展:GCC compile and link raw output
我正在尝试使用自定义__start
编译和链接一段代码。作为一个注释,我不要求它在任何已知的体系结构上工作,因此遵守任何规范并不重要,让它始终如一地工作。
我有一个简单的程序集(我从一个我现在无法找到的URL中获得)。
.set noreorder /* so we can use delay slots explicitly */
.text
.globl main
.globl __start
.type __start,@function
.ent __start
__start:
jal main;
nop;
li $0,1;
.end __start
如果我理解正确的话,所有这一切都是调用我的main方法,在分支延迟槽中执行no-op,然后将数字1写入寄存器0(我知道这违反了MIPS规范,它是故意的 - 它表示代码已完成,并且在实际发生之前被捕获。
但是,当我使用mips ld
使用此命令mips-linux-gnu-ld --section-start=.text=0 start.o main.o -o executable
使用objdump
00000000 <.pic.main>:
0: 3c190000 lui t9,0x0
4: 0800022b j 8ac <main>
8: 273908ac addiu t9,t9,2220
c: 00000000 nop
00000010 <__start>:
10: 0c000000 jal 0 <.pic.main>
14: 00000000 nop
18: 24000001 li zero,1
1c: 00000000 nop
.........
000008ac <main>
.........
无论我的测试程序多么微不足道,我总能获得相同的.pic.main
功能。但是,在某些情况下,它会显示在__start
之上,在某些情况下会显示在__start
以上。
我想删除这个&#34;功能&#34;完全,但失败,希望它始终出现在MinWidth
之后。
作为奖励,如果有人知道这个功能是什么或为什么会发生,我会很感兴趣。
答案 0 :(得分:2)
它看起来像一个与位置无关的跳转代码。链接器不知道你的东西将被放置在何处,因此它为所有情况创建了一个PIC。使用寄存器进行相对跳转或跳转可以解决问题,尽管它不会是跳转和链接。
我会尝试使用
-mrelax-pic-calls
将通常通过寄存器$t9
发送的PIC调用转为直接调用。只有链接器可以在链接时解析目标并且目标位于直接调用的范围内时,才可以执行此操作。mbranch-cost=num
将分支的成本设置为大致为“简单”的指令。 &#34;这个成本只是一种启发式方法,并不能保证在各个版本中产生一致的结果。&#34; -mno-shared
不生成与位置无关的代码,因此可以链接到共享库-mno-embedded-pic
我把钱放在前两个。