gpt4 book ai didi

c - JMP 不工作

转载 作者:太空宇宙 更新时间:2023-11-04 07:08:21 25 4
gpt4 key购买 nike

好的,所以我一直在尝试在汇编/C 中制作一个两步引导加载程序,但我无法让 JMP 工作。起初我以为读取失败了,但是经过以下测试我排除了这种可能性:

__asm__ __volatile__(
"xorw %ax, %ax;"
"movw %ax, %ds;"
"movw %ax, %es;"
"movb $0x02, %ah;"
"movb $0x01, %al;"
"movw $0x7E00, %bx;"
"movw $0x0003, %cx;"
"xorb %dh, %dh;"
"int $0x13;"
"movb 0x7E00, %al;"
"movb $0x0e, %ah;"
"int $0x10;"
//"jmp 0x7E00"
);

这按预期打印了“f”(扇区的第一个字节是 0x66,这是“f”的 ASCII 代码)证明读取成功,jmp 是问题所在。这是我的代码:

__asm__(".code16\n");
__asm__(".code16gcc\n");
__asm__("jmpl $0x0000, $main\n");
void main(){
__asm__ __volatile__(
"xorw %ax, %ax;"
"movw %ax, %ds;"
"movw %ax, %es;"
"movb $0x02, %ah;"
"movb $0x01, %al;"
"movw $0x7E00, %bx;"
"movw $0x0003, %cx;"
"xorb %dh, %dh;"
"int $0x13;"
"jmp $0x200;"
);
}

运行时,我的程序只是挂起,这意味着程序可能跳到了内存中的错误位置。顺便说一下,我显然是在 VMWare 播放器下以实模式运行它。我正在使用以下命令编译它:

gcc -c -0s -march=i686 -ffreestanding -Wall -Werror boot.c -o boot.o
ld -static -Ttest.ld -nostdlib --nmagic -o boot.elf boot.o --no-check-sections
objcopy -0 binary boot.elf boot.bin

这是test.ld:

ENTRY(main);
SECTIONS
{
. = 0x7C00;
.text : AT(0x7C00)
{
*(.test);
}
.sig : AT(0x7DFE)
{
SHORT(0xAA55);
}
}

注意:我已经确认这不是内联 asm 的问题 - 我也尝试了纯汇编实现并得到了相同的结果 - 我使用 C 的唯一原因是因为我计划稍微扩展它并且我是使用 C 循环和函数要舒服得多...

编辑:我已经上传了我的软盘驱动器的前三个扇区 here

编辑 2: 我一直无法使用任何建议让我的引导加载程序工作,并且根据@RossRidge 的建议,我编写了同一程序的汇编版本和一个简单的汇编回显输入的程序。可悲的是,这些也不起作用..

Bootstrap :

org 0x7c00
xor ax, ax
mov ds, ax
mov es, ax
mov ah, 0x02
mov al, 0x01
mov bx, 0x7E00
mov cx, 0x0003
xor dh, dh
int 0x13
jmp 0x7E00

部门 3 的计划:

xor ax, ax
int 0x16
mov ah, 0xe
int 0x10

它们都是用:nasm Linux/boot.S -o Linux/asm.bin 编译的,并且行为与它们的 C 对应物相同..

最佳答案

我很确定你的汇编程序生成了错误的跳转偏移量,它可能将 0x7e00 解释为当前文本部分中的相对值,但它被映射到 0x7c00链接器脚本,因此您的跳转可能会转到 0x7c00+0x7e00=0xfa00。作为一个丑陋的解决方法,您可以尝试 jmp 0x200 或使用间接跳转将其隐藏在您的工具中,例如 mov $0x7e00, %ax; jmp *%ax.或者 jmp .text+0x200 也可以。

另请注意,在 32 位 C 编译器中编写 16 位 asm 会生成错误代码,加载扇区的第一个字节为 0x66(操作数大小覆盖前缀)也暗示了这一点。由于编译器采用 32 位模式,它会生成带前缀的 16 位代码,当以 16 位模式运行时会切换回 32 位。一般来说,为此目的滥用内联 asm 不是一个好主意,您应该使用一个单独的 asm 文件并确保您告诉您的汇编器代码是为 16 位实模式设计的。

PS:学习使用调试器。


更新:当使用 nasm boot.asm -o boot.bin 组装时,以下代码在 qemubochs 中运行良好:

org 0x7c00
xor ax, ax
mov ds, ax
mov es, ax
mov ah, 0x02
mov al, 0x01
mov bx, 0x7E00
mov cx, 0x0003
xor dh, dh
int 0x13
jmp 0x7E00

times 510-($-$$) db 0
dw 0xaa55
; second sector
times 512 db 0
; Program in sector 3:
xor ax, ax
int 0x16
mov ah, 0xe
int 0x10
jmp $
times 1536-($-$$) db 0

您可以下载 image here (限时优惠 ;))。

关于c - JMP 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30417478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com