两部分问题。
我正在将引导加载程序组件与C结合使用。
1)问题是从汇编到链接C对象的调用一切都停止了。并挂起。
即使是只返回的功能,也不会执行任何操作。问题在哪里? 编译,链接,代码......?我已经通过GDB获得了不太成功。
2)其次,我读到一个应该做一个长跳以对齐内存由于一些
使用反向寻址的BIOS版本。但是 - 如何用long编译文件
跳转也有.code16
或16位模式设置?继续
(.text+0x76): relocation truncated to fit: R_386_16 against `.text'
之类的。尝试使用各种标志等as
和gcc
但是没有运气。
我注意到, GRUB和大多数人一样,混合.code16
和ljump
等
操作以及使用32位寄存器。
核心程序集文件的基础是:
.file "core.s"
.text
.code16 /* 16 bit mode */
.globl _start, start;
_start:
start:
jmp POST_BPB
nop
.= _start + 0x64
POST_BPB:
cli /* Disable interrupts. */
xorw %ax,%ax
movw %ax,%ds /* Data Segment */
movw %ax,%ss /* Stack Segment */
movw 0x7c00, %sp /* Stack Pointer */
sti /* OK */
movb $0x21, %al /* Print ! */
movb $0x0e, %ah
int $0x10
movb $0x22, %al /* Print " */
movb $0x0e, %ah
int $0x10
/* --------------------------------------------------------- */
/* HERE: On this call everything goes in some eternal loop. */
call base_test
/* --------------------------------------------------------- */
movb $0x25, %al /* Print $ */
movb $0x0e, %ah
int $0x10
. = _start + 0x1fe
.word 0xaa55 /* MBR Signature at offset 510 */
C文件使用相同的打印例程:
asm(".code16gcc\n");
extern void base_test()
{
asm(
"movb $0x23, %al\n\t"
"movb $0x0e, %ah\n\t"
"int $0x10\n\t"
"ret\n"
);
return;
}
由(除其他方式)建立:
gcc -Wall -W -m32 -nostdinc -c base_test.c
as core.s -o core.o
ld -static -nostdlib --nmagic -o boot.elf core.o base_test.o
objcopy -O binary boot.elf boot.img
运行:
qemu-system-i386 boot.img
编辑
行。通常作为一个人要求找到。要编译16位代码,请使用以下标志
链接器标志与gcc:-Wl,-Ttext,0x7C00
。 (0x7C00是内存世界中的基本魔法。)
gcc -nostdlib -Wl,-Ttext,0x7C00 -o out.o in.s