重新定位后的截断以适合`.text'16:

问题描述 投票:1回答:1

我希望你们过得愉快。我有一个关于将汇编编译为.bin的问题。我正在尝试使用This article进行修复,但即使这样,我也会得到“重新定位截断以适合:16对'.text'。

bootReal.s

#generate 16-bit code
.code16

#hint the assembler that here is the executable code located
.text
.globl _start;
#boot code entry
_start:
      jmp _boot                           #jump to boot code
      welcome: .asciz "Hello, World\n\r"  #here we define the string

     .macro mWriteString str              #macro which calls a function to print a string
          leaw  \str, %si
          call .writeStringIn
     .endm

     #function to print the string
     .writeStringIn:
          lodsb
          orb  %al, %al
          jz   .writeStringOut
          movb $0x0e, %ah
          int  $0x10
          jmp  .writeStringIn
     .writeStringOut:
     ret

_boot:
     mWriteString welcome

     #move to 510th byte from the start and append boot signature
     . = _start + 510
     .byte 0x55
     .byte 0xaa

我使用的命令:

as bootReal.s -o bootReal.s

ld.exe -o file.tmp bootReal.o

任何帮助将不胜感激!

assembly bootloader 16-bit
1个回答
0
投票

((。text + 0x1f):重定位被截断以适合:R_386_16相对于'.text']

如果使用的是64位工具链,则错误可能会稍有不同,但类似于R_???????_16 against '.text'

要解决此问题,您可以创建自己的链接描述文件,也可以在LD命令行上将基本VMA设置为适当的值。我建议使用-Ttext=0x7c00并在引导程序中将DS设置为0x0000。

我有General Bootloader个技巧,这些技巧讨论了编写引导加载程序的许多问题。您不应假定引导加载程序正在运行时,段寄存器具有任何特定值。如果将-Ttext=0x7c00用作VMA(ORG),则需要将DS设置为零。 segment:offset对0x0000:0x7c00 =物理地址0x07c00(0x0000 << 4 + 0x7c00)。 0x07c00是旧版BIOS将引导扇区加载到内存中的位置。

如果您遇到类似以下的重定位错误:

((。text + 0x1f):重定位被截断以适合:R_386_16相对于'.text']

您可以始终使用OBJDUMP来显示目标文件中的重定位条目。在这种情况下,由于您正在编写16位代码,因此您将需要OBJDUMP转储该代码(-D)并解码为16位代码(-Mi8086)。 objdump -Mi8086 -Dr bootReal.o的输出看起来与此类似(它可能因所使用的链接器而异):

00000000 <_start>: 0: eb 1b jmp 1d <_boot> 00000002 <welcome>: 2: 48 dec %ax 3: 65 gs 4: 6c insb (%dx),%es:(%di) 5: 6c insb (%dx),%es:(%di) 6: 6f outsw %ds:(%si),(%dx) 7: 2c 20 sub $0x20,%al 9: 57 push %di a: 6f outsw %ds:(%si),(%dx) b: 72 6c jb 79 <_boot+0x5c> d: 64 0a 0d or %fs:(%di),%cl ... 00000011 <.writeStringIn>: 11: ac lods %ds:(%si),%al 12: 08 c0 or %al,%al 14: 74 06 je 1c <.writeStringOut> 16: b4 0e mov $0xe,%ah 18: cd 10 int $0x10 1a: eb f5 jmp 11 <.writeStringIn> 0000001c <.writeStringOut>: 1c: c3 ret 0000001d <_boot>: 1d: 8d 36 02 00 lea 0x2,%si 1f: R_386_16 .text 21: e8 ed ff call 11 <.writeStringIn> ... 1fc: 00 00 add %al,(%bx,%si) 1fe: 55 push %bp 1ff: aa stos %al,%es:(%di)

在重定位错误中,.text+0x1f被认为是问题的根源。如果您查看OBJDUMP输出,则有一个重定位条目:

1d: 8d 36 02 00 lea 0x2,%si 1f: R_386_16 .text

此重定位与其上方的指令相关联。实质上,这意味着链接器尝试为LEA指令生成和偏移,但该值无法用16位值表示。
SI是16位寄存器,并且不能在其中添加值,该值> = 0x10000。
© www.soinside.com 2019 - 2024. All rights reserved.