(NASM)(80x86)引导加载程序需要xor ax,ax
我正在学习如何从osdev制作引导加载程序。我使用NASM来组装代码,使用x86机器来运行引导加载程序。这是一段打印字符并进入无限循环的小代码:(NASM)(80x86)引导加载程序需要xor ax,ax,x86,nasm,bootloader,X86,Nasm,Bootloader,我正在学习如何从osdev制作引导加载程序。我使用NASM来组装代码,使用x86机器来运行引导加载程序。这是一段打印字符并进入无限循环的小代码: BITS 16 xor ax, ax mov ah, 0x0E mov al, 0x41 int 0x10 jmp $ times 510-($-$$) db 0x00 db 0x55 db 0xAA 我的问题是:为什么在注释'xor ax,ax'指令时代码不运行?正如您在上面的代码中看到的,ax值被更改以存储中断参数,因此代码应该在没有xo
BITS 16
xor ax, ax
mov ah, 0x0E
mov al, 0x41
int 0x10
jmp $
times 510-($-$$) db 0x00
db 0x55
db 0xAA
我的问题是:为什么在注释'xor ax,ax'指令时代码不运行?正如您在上面的代码中看到的,ax值被更改以存储中断参数,因此代码应该在没有xor指令的情况下运行
附加说明:
- 我正在使用以下命令在Xubuntu下汇编代码: nasm-f bin-o main.bin main.asm
- 我使用以下命令将512字节的机器代码存储到笔驱动器上: sudo dd if=main.bin of=/dev/sdb
- 我的电脑可以从笔驱动启动
xor ax,ax
指令的存在不会影响引导。但是,您应该包括一个异或bh,bh(更多信息)
不幸的是,这只是理论。 特别是对于USB设备,某些固件隐式地采用BPB,包括完整的FDC描述符(具有有效的操作系统名称)。
非常感谢您强调这一点 自从引入实现,特别是处理遗留引导的部分以来,编写完全支持的MBR变得很棘手 固件有时会尝试自动检测要使用的引导模式,因为所有UEFI设备也是符合规范的遗留设备,固件必须依靠一些怪癖来区分它们 我的固件将设备检测为“遗留”,即使明确告知,也仅当至少其中一项为真时才检测到该设备:
- MBR分区表中有一个可引导的非空分区。
CHS或LBA中的起始/结束地址根本不检查 - 第一条指令是
(可以是xor ax,ax
或33 C0
)。 这是因为大多数引导加载程序要做的第一件事是通过AX将段寄存器设置为零31 C0
您可以使用
xor ax,ax
(在这种情况下,我建议使用db 33h,0c0h
和一条注释作为文档)或添加一个虚拟分区条目,如下所示
BITS 16
ORG 7c00h ;Soon or later you'll need this
xor bh, bh
mov ah, 0x0E
mov al, 0x41
int 0x10
_loop:
hlt ;Be eco-friendly
jmp _loop
;Pad to the first PTE (Partition Table Entry), it is at 1beh
TIMES 01beh-($-$$) db 00h
dd 80h ;Bootable partition at CHS 0:0:0 (Which is illegal but not checked)
db 01h ;Non empty partition (Type 1 is MS-DOS 2.0 FAT)
;Pad to the end of the sector minus 2
TIMES 510-($-$$) db 00h
dw 0aa55h ;Signature
1根据
dd
命令的参数 现在是2018年,我偶然发现了同样的问题。Micheal的回答和评论似乎是迄今为止最好的解决方案。我们并不是生活在一个完美的世界里,事实就是如此。这就是为什么我在启动OS Dev时想要开发BIOS。我讨厌在我的计算机上运行别人的代码而不检查它。但这对于固件和bios来说太难了。如果你在不知道自己在做什么的情况下乱用BIOS,它甚至可能会损坏你的电脑
不管怎样,我刚刚添加了这条评论,以防以后有人碰到同样的问题。我会认真地建议检查源代码和/或反向工程一些已经可用的引导加载程序,如GRUB、Windows引导管理器、LILO等。您还可以为您的PC下载live USB linux发行版,将其安装在闪存驱动器中,并在十六进制编辑器中查看引导扇区代码,甚至可以将其反汇编
这不完全是对这个问题的回答,但值得一提。为了使这一点更加相关,我可以说的是,我颠倒了安装在Kali Linux USB bootable上的GRUB代码,它以一条
XOR BP,BP
指令开始。通常在引导加载程序文件的顶部有org 0x7c00
,在XOR ax、ax之后,如果需要,可以将其复制到DS寄存器和ES(不痛)在<代码> MOV DS、AX <代码> >代码> MOVE ES、AX <代码> XOR AX、AX < /代码> .Case> XOR AX、AX < /C> >与AX-AUX完全相同。因为您在AX和AL正确的情况下重写AH和AL,如果代码“XOR AX,AX < /代码>完成或不执行。您确定它是否有不同的工作?还应该考虑设置SS:SP。(堆栈段和指针)唯一的另一种可能性是BIOS正在(盲目地)覆盖它认为是BPB的内容,而BPB通常出现在引导加载程序的开头(通常在JMP指令之后)如果盲目更新引导程序,可能是在代码加载到RAM中之后BIOS所做的修改导致代码不正确。我建议您在int 10H/AH=0EH之前考虑做“代码> XOR BX、BX < /代码>,因为BH被假定为要写入的页码(设置为0)。。可以找到有关BIOS参数块的更多信息。xor ax,ax
在一个工作的引导加载程序中根本不需要。真实的硬件有一些奇怪的怪癖,你在bochs、qemu、virtualbox等虚拟环境中通常看不到。@RyanB:见Peter的答案。他有。IRC聊天中也提到过。我暗示了这个想法恩,我提到“真正的硬件有一些奇怪的怪癖,你在bochs、qemu、virtualbox等虚拟环境中通常看不到。”但作为一个暗示,它可能有点迟钝。哈哈,我会再次投票支持这个环保评论:)认为您不需要BPB是错误的。您可能不使用太多实际的硬件,但在USB引导过程中,许多BIOS会写入介质的驱动器几何图形(如BIOS所示)进入BPB区域。如果您有BIOS认为BPB所在的代码,一些BIOS会盲目地向该区域写入BPB。其他BIOS会尝试检查USB设备的第一条指令是否为JMP指令(有些是哑指令,甚至不检查它是否为2)