今天嘗試寫我的第一個裸機程序,虛擬機使用bochs,這個虛擬機配置很容易,也比較簡單,非常新手。

 1# bochs 配置文件
 2
 3# 設置Bochs 在運行過程中能夠使用的內存,32MB
 4megs: 32
 5
 6# BIOS和顯示BIOS
 7romimage: file=/home/admin123/Desktop/bochs/share/bochs/BIOS-bochs-latest
 8vgaromimage: file=/home/admin123/Desktop/bochs/share/bochs/VGABIOS-lgpl-latest
 9
10# 軟盤,不用
11# floppya: 1_44=a.img, status=inserted
12
13# 使用硬盤
14# boot: floppy
15boot: disk
16
17# 日誌文件的輸出。
18log: bochs.out
19
20# 關閉鼠標
21mouse: enabled=0
22keyboard_mapping: enabled=1,map=/home/admin123/Desktop/bochs/share/bochs/keymaps/x11-pc-us.map
23
24# 硬盤設置
25ata0-master: type=disk, path="hd60M.img", mode=flat, cylinders=121, heads=16, spt=63
26ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
27
28# gdb的支持,1234 端口調試
29gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0
 1[org 0x7c00]
 2[bits 16]
 3BOOT_MAIN_ADDR equ 0x500
 4readdiskmsg db "ReadDisk...", 0
 5
 6global _start
 7
 8_start:
 9    xor ax, ax
10    mov ds, ax
11    mov es, ax
12    mov ss, ax
13    mov fs, ax
14    mov sp, 0x7c00
15
16    mov ax, 3
17    int 0x10
18
19    mov ecx, 2
20    mov bl, 2
21
22    mov dx, 0x1f2
23    mov al, bl
24    out dx, al
25
26    inc dx
27    mov al, cl
28    out dx, al
29
30    inc dx
31    mov al, ch
32    out dx, al
33
34    inc dx
35    shr ecx, 16
36    mov al, cl
37    out dx, al
38
39    inc dx
40    mov al, ch
41    and al, 0b1110_1111
42    out dx, al
43
44    inc dx
45    mov al, 0x20
46    out dx, al
47
48    mov si, readdiskmsg
49    call print
50
51.hd_ready_check:
52    mov dx, 0x1f7
53    in al, dx
54    and al, 0b0000_1000
55    cmp al, 0b0000_1000
56    jnz .hd_ready_check
57
58    mov dx, 0x1f0
59    mov cx, 256
60    mov edi, BOOT_MAIN_ADDR
61
62.read_boot:
63    in ax, dx
64    mov [edi], ax
65    add edi, 2
66    loop .read_boot
67
68    jmp BOOT_MAIN_ADDR
69
70;; mov si, string
71;; call print
72print:
73    mov ah, 0x0e
74    mov bh, 0
75    mov bl, 0x01
76.print_loop:
77    mov al, [si]
78    cmp al, 0
79    jz .print_done
80    int 0x10
81
82    inc si
83    jmp .print_loop
84
85.print_done:
86    ret
87
88times 510 - ($ - $$) db 0
89db 0x55, 0xaa

彙編具體就不解釋了,太累了。

我沒有在這個代碼裡分段,因為分段之後編譯出來的二進制會有內存對齊,導致最後大小不是512字節。

運行效果:

image.png