我希望你们过得愉快。我有一个关于将汇编编译为.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
任何帮助将不胜感激!
((。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。