使用gas,ld,objcopy编译具有绝对寻址的汇编代码

时间:2015-10-03 21:38:44

标签: assembly ld gas objcopy

我试图为在MEMU模拟的MIPS Malta电路板编写一些启动代码。

据我了解,马耳他电路板将4MB代码从闪存加载到物理RAM中的特定位置(0x1fc00000,即MIPS程序地址空间中的0xbfc00000:MIPS32复位中断位置)。我正在尝试生成将在此位置加载和运行的代码。

我有一个简单的汇编程序,它永远循环:

        .text
_start:
        b _start

当我用GNU汇编程序组装它时,我得到一个带有包含此代码的.text部分的ELF文件。用objdump拆解它:

Disassembly of section .text:

00000000 <_start>:
   0:   1000ffff        b       0 <_start>
   4:   00000000        nop
        ...

使用链接描述文件我可以将.text部分重定位到0x8fc00000,此时反汇编产生:

Disassembly of section .text:

8fc00000 <_start>:
8fc00000:       1000ffff        b       8fc00000 <_start>
8fc00004:       00000000        nop
        ...

由于ELF文件包含其他不可执行的部分,ELF标题等,我使用objcopy只转储文本部分:

mips-freebsd-objcopy -O binary --only-section .text boot.o.ld boot.bin

但是,由于分支操作数仍然是相对的,因此结果代码不使用绝对寻址并且分支到0x0而不是0x8fc00000:

% mips-freebsd-objdump -D -m mips -b binary boot.bin

boot.bin:     file format binary


Disassembly of section .data:

00000000 <.data>:
   0:   ffff0010        b       0x0
   4:   00000000        nop
        ...

我徒劳地搜索了objcopy或ld的标志,它会将相对地址解析为输出中的绝对地址。有objcopy标志来操作节开始地址,但我相信这些只是改变了输出格式的偏移表,所以不会影响二进制输出(显然没有这样的表)。

到目前为止,我发现的唯一解决方法是在汇编源中添加.org指令:

        .org 0x8fc00000

这可以理解地产生一个带有零的~2GB文件前置填充,但产生的代码具有绝对寻址,我可以将其删除。

有没有正确的方法呢?

0 个答案:

没有答案