【发布时间】:2015-12-20 16:32:31
【问题描述】:
我正在学习汇编,并尝试编写自己的引导加载程序。它在 VirtualBox 上运行良好,但在实际 PC 上无法运行。 在电脑上“Hello World!”没有打印出来。
这是使用的代码:
BITS 16
ORG 0x7C00
jmp boot_sector
;------------------------------
OEMLabel db "FLOPPYDR"
BytesPerSector dw 512
SectorsPerCluster db 1
ReservedForBoot dw 1
NumberOfFats db 2
RootDirEntries dw 224
LogicalSectors dw 2880
MediumByte db 0xF0
SectorsPerFat dw 9
SectorsPerTrack dw 18
Sides dw 2
HiddenSectors dd 0
LargeSectors dd 0
DriveNo dw 0
Signature db 41
VolumeID dd 0x00
VolumeLabel db "FLOPPYDRIVE"
FileSystem db "FAT12"
;##############################
boot_sector:
;##############################
mov ax, 0x0000 ; Set up the stack
mov ss, ax ; Is this done correctly?
mov sp, 0x7C00 ; (I dont quite understand)
int 0x10 ; Set video mode
int 0x13 ; Reset the drive
mov ah, 0x02 ; Read more sectors
mov al, 2 ; Read two extra sectors,
mov bx, main_sector ; starting from the second.
mov ch, 0 ;
mov cl, 2 ; dl has been set already (?)
mov dh, 0 ;
int 0x13 ;
mov [bootdev], dl ; Store original dl in bootdev
jmp main_sector ; Go to the main sector (0x200 I think)
times 510 - ($ - $$) db 0 ; Fill in the rest of the sector with 0s
dw 0xAA55 ; and 0xAA55 at the end for signature
;##############################
main_sector:
;##############################
jmp Start
;------------------------------
bootdev db 0
msg db 'Hello World!', 10, 13, 0
;------------------------------
print_string:
mov ah, 0x0E
mov bh, 0
cmp al, 0
jne .loop
mov bl, 0x0F
.loop:
lodsb
cmp al, 0
je .end
int 0x10
jmp .loop
.end:
ret
;------------------------------
Start:
mov si, msg
call print_string
hlt
times 512 - ($ - main_sector) db 0
我还评论了一些问题,但这些不是我的主要问题(好吧,也许我不知道答案会导致问题)。为什么这不能在真正的 PC 上运行?
编译我使用nasm -f bin boot.asm -o boot.bin,创建一个虚拟软盘文件我使用mkfile 1474560 floppy.flp
然后我使用 HexEdit 打开 floppy.flp 并将前 64 行 (0x00 - 0x3F) 替换为 boot.bin 文件的内容(使用 HexEdit 打开)。
E9 38 00 46 4C 4F 50 50 59 44 52 00 02 01 01 00
02 E0 00 40 0B F0 09 00 12 00 02 00 00 00 00 00
00 00 00 00 00 00 29 00 00 00 00 46 4C 4F 50 50
59 44 52 49 56 45 46 41 54 31 32 B8 00 00 8E D0
BC 00 7C CD 10 CD 13 B4 02 B0 02 BB 00 7E B5 00
B1 02 B6 00 CD 13 88 16 03 7E E9 A3 01 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA <-- End of first sector
E9 24 00 00 48 65 6C 6C 6F 20 57 6F 72 6C 64 21
0A 0D 00 B4 0E B7 00 3C 00 75 02 B3 0F AC 3C 00
74 04 CD 10 EB F7 C3 BE 04 7E E8 E6 FF F4 00 00 (The rest is just 0's).
这是我将floppy.flp刻录到U盘时的终端:
Last login: Wed Sep 23 12:10:48 on ttys000
MacBook-Air:~ sasha$ cd ~/Desktop
MacBook-Air:Desktop sasha$ diskutil list
/dev/disk0
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *121.3 GB disk0
1: Apple_HFS 209.7 MB disk0s1
2: Apple_CoreStorage 120.5 GB disk0s2
3: Apple_Boot Recovery HD 650.0 MB disk0s3
/dev/disk1
#: TYPE NAME SIZE IDENTIFIER
0: Apple_HFS Macintosh HD *120.1 GB disk1
Logical Volume on disk0s2
8CD6A846-395D-4C97-A5DE-0A7ABA9F1C99
Unencrypted
/dev/disk2
#: TYPE NAME SIZE IDENTIFIER
0: Apple_partition_scheme *17.1 MB disk2
1: Apple_partition_map 32.3 KB disk2s1
2: Apple_HFS Flash Player 17.1 MB disk2s2
/dev/disk3
#: TYPE NAME SIZE IDENTIFIER
0: FLOPPYDRIVE *1.0 GB disk3
MacBook-Air:Desktop sasha$ diskutil unmountdisk /dev/disk3
Unmount of all volumes on disk3 was successful
MacBook-Air:Desktop sasha$ sudo dd bs=512 if=floppy.flp of=/dev/disk3
Password:
2880+0 records in
2880+0 records out
1474560 bytes transferred in 0.843982 secs (1747146 bytes/sec)
MacBook-Air:Desktop sasha$
【问题讨论】:
-
我最近用
general tips on developing a bootloaderhere写了一个答案。第 1、2、3 点及其解决方案可能对您有所帮助。 -
在您的情况下,您可能还需要通过将
NOP指令放在右侧之后jmp boot_sector来对齐磁盘数据结构 -
特定于您的情况 ES 和 DS 将是一个重要因素。
lodsb需要 DS,int 0x13 需要正确的 ES,因为它需要 ES:BX 中的完整地址磁盘缓冲区。由于您使用lodsb,因此您应该在设置堆栈后使用cld清除方向标志,以便保证lodsb在每次执行后递增SI。 -
@MichaelPetch 它肯定有效,再次感谢您!
-
那我将把这个花絮添加到我的答案中。遇到这个问题的其他人可能会从中受益。
标签: macos assembly nasm x86-16 bootloader