[代码及玩法如下]
----------------
将代码编译成Bin文件后,读写引导扇区并做成虚拟软盘镜像,在Bochs或VMWare中启动,就能看到效果了
(就像tiamo前辈所说的那样,在有源代码的情况下,合格的程序员不应该被编译/编译选项难倒~)
PS: 代码里还用到了 BIOS INT 10号中断-06号功能调用 —— 清屏(屏幕向上滚动)
; ============================================ ;
; .: keenjoy95 2007 :. ;
; .: keenjoy95_at_gmail_dot_com :. ;
; -------------------------------------------- ;
; 代码描述 : 引导扇区演示程序 ;
; 编译方法 : nasm boot.asm -o boot.bin ;
; ============================================ ;
; 为了对齐的美观, 下面的代码向前进缩了一些...
org 07c00h ; ORG伪指令也被称为程序起始地址伪指令 / 定位伪指令
; 该伪指令用于指示编译器(链接器)将其后续代码(段)定位于指定地址
; 由于本示例是引导扇区演示程序,所以目标定位地址为0000:7c00h
jmp MYOS_ENTRY ; 无条件跳转到程序的入口点MYOS_ENTRY标号处
BootMessage:
db 0x07 ; "Beep"
dw 0x1048 ; "H" (蓝底 黑字)
dw 0x1465 ; "e" (蓝底 红字)
dw 0x1f6c ; "l" (蓝底 白字)
dw 0x126c ; "l" (蓝底 绿字)
dw 0x166f ; "o" (蓝底 棕字)
dw 0xfc2c ; "," (白底浅红字)
dw 0xf020 ; " " (白底 黑字)
dw 0x4b4d ; "M" (红底浅青字)
dw 0x4179 ; "y" (红底 蓝字)
dw 0x404f ; "O" (红底 黑字)
dw 0x4f53 ; "S" (红底 白字)
dw 0x4c21 ; "!" (红底浅红字)
db 0x07 ; "Beep"
ScrollWindows:
mov ax, 0600h ; AH 赋值为功能号06h(窗口上滚) (BIOS INT 10-06h 定义参数)
; AL 赋值为0, 窗口信息全部移出(清屏) (BIOS INT 10-06h 定义参数)
mov bx, 0700h ; BH 底部空白行属性赋值为黑底灰白字 (BIOS INT 10-06h 定义参数)
; BL 保留
mov cx, 0000h ; 窗口左上角的行列、号赋值为00h 00h (BIOS INT 10-06h 定义参数)
mov dx, 184fh ; 窗口右下角的行列、号赋值为18h 4fh (BIOS INT 10-06h 定义参数)
; ---------------------------------------------------
; 0(00h) 79(4fh)
; 0(00h)┏━━━━━━━━━━━━━━━━┓
; ┃ ┃
; ┃ ┃
; ┃ ┃
; ┃ 显示器 25*80 显示方式 ┃
; ┃ ┃
; ┃ ┃
; ┃ ┃
; 24(18h)┗━━━━━━━━━━━━━━━━┛
;
int 10h ; BIOS 10h号中断-06h号功能 (清屏功能调用)
ret ; 子程序无参数返回
DisplayString:
mov ax, BootMessage ; 取字符串数据(段)的首地址
mov bp, ax ; ES:BP 赋值为待显示字符串的首地址 (BIOS INT 10-13h 定义参数)
mov cx, 14 ; CX 赋值为字符串长度(此处为固定值) (BIOS INT 10-13h 定义参数)
mov ax, 01303h ; AH 赋值为功能号13h(显示字符串) (BIOS INT 10-13h 定义参数)
; AL 输出模式参数赋值为03h (BIOS INT 10-13h 定义参数)
; ---------------------------------------------------
; 第 0 位 : 在输出之后更新光标位置
; 第 1 位 : 字符串包含交替的字符和属性
;
mov bx, 0000h ; BH 页号赋值为0 (BIOS INT 10-13h 定义参数)
; BL 属性赋值为黑底浅红字(属性字BL使用的前提为AL的高位置0)
; ---------------------------------------------------
; 16位色彩编码表 (D7 D6 D5 D4为背景色,D3 D2 D1 D0为前景色)
; ┏━━━━━━━━━━━┳━━━━━━━━━━━┓
; ┃ 0 0 0 0 黑 ┃ 1 0 0 0 灰 ┃
; ┃ 0 0 0 1 蓝 ┃ 1 0 0 1 浅蓝 ┃
; ┃ 0 0 1 0 绿 ┃ 1 0 1 0 浅绿 ┃
; ┃ 0 0 1 1 青 ┃ 1 0 1 1 浅青 ┃
; ┃ 0 1 0 0 红 ┃ 1 1 0 0 浅红 ┃
; ┃ 0 1 0 1 品红 ┃ 1 1 0 1 浅品红 ┃
; ┃ 0 1 1 0 棕 ┃ 1 1 1 0 黄 ┃
; ┃ 0 1 1 1 灰白 ┃ 1 1 1 1 白 ┃
; ┗━━━━━━━━━━━┻━━━━━━━━━━━┛
;
mov dx, 0000h ; DL 赋值为字符串显示的起始行、列号 (BIOS INT 10-13h 定义参数)
int 10h ; BIOS 10h号中断-13h号功能 (字符串屏显功能调用)
ret ; 子程序无参数返回
MYOS_ENTRY:
mov ax, cs ; ┓
mov ds, ax ; ┣ 段寄存器初始化
mov es, ax ; ┛
call ScrollWindows ; 调用清屏子程序
call DisplayString ; 调用字符串显示子程序
jmp $ ; 主程序进入无限循环
MYOS_PAD:
times 510-($-$$) db 0 ; 循环填充剩余空间,使生成的二进制代码大小恰好为一个扇区(512Byte)
dw 0xAA55 ; 引导扇区结束标志
; ---8<----------- [Cut Here] ----------->8--- ;
; .: keenjoy95 2007 :. ;
; .: keenjoy95_at_gmail_dot_com :. ;
; ! NO rights reserved ! ;
; -------------------------------------------- ;
如你所见,每一个输出的字符都可以拥有不同的“背景色”和“前景色”~
代码的注释里我给出了16位的色彩编码表。
然后(也就是现在),小的我眯过午觉了~
再反汇编学习一下,我知道这个很“弱智”,不过~人嘛,都是从弱智开始的,更何况ndisasm反汇编功能更弱智~ :P
; ==================================================== ;
; .: keenjoy95 2007 :. ;
; .: keenjoy95_at_gmail_dot_com :. ;
; ---------------------------------------------------- ;
; 代码描述 : 引导扇区演示程序反汇编 ;
; 逆向方法 : ;
; ndisasm -o 0x7c00 boot.bin >> disboot.asm ;
; ndisasm -o 0x7c00 -k 3,26 boot.bin >> disboot.asm ;
; ==================================================== ;
00007C00 E93D00 jmp 0x7c40 ; 无条件跳转到程序的入口点
; 跳转的指令是"E9 3D00" (地址偏移是003D, 向后
; 跳61D/0x3DH个字节)
;------------------------------------------------------;
; * 下面是错误的反汇编 —— 数据段 * ;
;------------------------------------------------------; "Hello, MyOS!"
00007C03 07 pop es ; "Beep"
00007C04 48 dec ax ; "H"
00007C05 106514 adc [di+0x14],ah ; (0x10) | "e" | (0x14)
00007C08 6C insb ; "l"
00007C09 1F pop ds ; (0x1f)
00007C0A 6C insb ; "l"
00007C0B 126F16 adc ch,[bx+0x16] ; (0x12) | "o" | (0x16)
00007C0E 2CFC sub al,0xfc ; "," | (0xfc)
00007C10 20F0 and al,dh ; " " | (0xf0)
00007C12 4D dec bp ; "M"
00007C13 4B dec bx ; (0x4b)
00007C14 7941 jns 0x7c57 ; "y" | (0x41)
00007C16 4F dec di ; "O"
00007C17 40 inc ax ; (0x40)
00007C18 53 push bx ; "S"
00007C19 4F dec di ; (0x4f)
00007C1A 214C07 and [si+0x7],cx ; "!" | (0x4c) | "Beep"
;------------------------------------------------------;
; * 代 码 段 * ;
;------------------------------------------------------;
00007C1D B80006 mov ax,0x600 ; ┓
00007C20 BB0007 mov bx,0x700 ; ┃
00007C23 B90000 mov cx,0x0 ; ┣ 清屏子程序
00007C26 BA4F18 mov dx,0x184f ; ┃
00007C29 CD10 int 0x10 ; ┛
00007C2B C3 ret ; 子程序无参数返回
00007C2C B8037C mov ax,0x7c03 ; ┓
00007C2F 89C5 mov bp,ax ; ┃
00007C31 B90E00 mov cx,0xe ; ┃
00007C34 B80313 mov ax,0x1303 ; ┣ 字符串显示子程序
00007C37 BB0000 mov bx,0x0 ; ┃
00007C3A BA0000 mov dx,0x0 ; ┃
00007C3D CD10 int 0x10 ; ┛
00007C3F C3 ret ; 子程序无参数返回
00007C40 8CC8 mov ax,cs ; ┓
00007C42 8ED8 mov ds,ax ; ┣ 段寄存器初始化
00007C44 8EC0 mov es,ax ; ┛
00007C46 E8D4FF call 0x7c1d ; 跳转的指令是"E8 D4FF" (地址偏移是FFD4, 向前
; 跳44D/0x2CH个字节)
00007C49 E8E0FF call 0x7c2c ; 跳转的指令是"E8 E0FF" (地址偏移是FFE0, 向前
; 跳32D/0x20H个字节)
00007C4C EBFE jmp short 0x7c4c ; 主程序进入无限循环
; 跳转的指令是"E8 FE" (地址偏移是00FE, 向前
; 跳2D个字节, 进入死循环)
;------------------------------------------------------;
; * 下面是错误的反汇编 —— 引导区填充段及结束标志 * ;
;------------------------------------------------------;
00007C4E 0000 add [bx+si],al
00007C50 0000 add [bx+si],al
00007C52 0000 add [bx+si],al
00007C54 0000 add [bx+si],al
00007C56 0000 add [bx+si],al
00007C58 0000 add [bx+si],al
00007C5A 0000 add [bx+si],al
00007C5C 0000 add [bx+si],al
00007C5E 0000 add [bx+si],al
00007C60 0000 add [bx+si],al
00007C62 0000 add [bx+si],al
00007C64 0000 add [bx+si],al
00007C66 0000 add [bx+si],al
00007C68 0000 add [bx+si],al
00007C6A 0000 add [bx+si],al
00007C6C 0000 add [bx+si],al
00007C6E 0000 add [bx+si],al
00007C70 0000 add [bx+si],al
00007C72 0000 add [bx+si],al
00007C74 0000 add [bx+si],al
00007C76 0000 add [bx+si],al
00007C78 0000 add [bx+si],al
00007C7A 0000 add [bx+si],al
00007C7C 0000 add [bx+si],al
00007C7E 0000 add [bx+si],al
00007C80 0000 add [bx+si],al
00007C82 0000 add [bx+si],al
00007C84 0000 add [bx+si],al
00007C86 0000 add [bx+si],al
00007C88 0000 add [bx+si],al
00007C8A 0000 add [bx+si],al
00007C8C 0000 add [bx+si],al
00007C8E 0000 add [bx+si],al
00007C90 0000 add [bx+si],al
00007C92 0000 add [bx+si],al
00007C94 0000 add [bx+si],al
00007C96 0000 add [bx+si],al
00007C98 0000 add [bx+si],al
00007C9A 0000 add [bx+si],al
00007C9C 0000 add [bx+si],al
00007C9E 0000 add [bx+si],al
00007CA0 0000 add [bx+si],al
00007CA2 0000 add [bx+si],al
00007CA4 0000 add [bx+si],al
00007CA6 0000 add [bx+si],al
00007CA8 0000 add [bx+si],al
00007CAA 0000 add [bx+si],al
00007CAC 0000 add [bx+si],al
00007CAE 0000 add [bx+si],al
00007CB0 0000 add [bx+si],al
00007CB2 0000 add [bx+si],al
00007CB4 0000 add [bx+si],al
00007CB6 0000 add [bx+si],al
00007CB8 0000 add [bx+si],al
00007CBA 0000 add [bx+si],al
00007CBC 0000 add [bx+si],al
00007CBE 0000 add [bx+si],al
00007CC0 0000 add [bx+si],al
00007CC2 0000 add [bx+si],al
00007CC4 0000 add [bx+si],al
00007CC6 0000 add [bx+si],al
00007CC8 0000 add [bx+si],al
00007CCA 0000 add [bx+si],al
00007CCC 0000 add [bx+si],al
00007CCE 0000 add [bx+si],al
00007CD0 0000 add [bx+si],al
00007CD2 0000 add [bx+si],al
00007CD4 0000 add [bx+si],al
00007CD6 0000 add [bx+si],al
00007CD8 0000 add [bx+si],al
00007CDA 0000 add [bx+si],al
00007CDC 0000 add [bx+si],al
00007CDE 0000 add [bx+si],al
00007CE0 0000 add [bx+si],al
00007CE2 0000 add [bx+si],al
00007CE4 0000 add [bx+si],al
00007CE6 0000 add [bx+si],al
00007CE8 0000 add [bx+si],al
00007CEA 0000 add [bx+si],al
00007CEC 0000 add [bx+si],al
00007CEE 0000 add [bx+si],al
00007CF0 0000 add [bx+si],al
00007CF2 0000 add [bx+si],al
00007CF4 0000 add [bx+si],al
00007CF6 0000 add [bx+si],al
00007CF8 0000 add [bx+si],al
00007CFA 0000 add [bx+si],al
00007CFC 0000 add [bx+si],al
00007CFE 0000 add [bx+si],al
00007D00 0000 add [bx+si],al
00007D02 0000 add [bx+si],al
00007D04 0000 add [bx+si],al
00007D06 0000 add [bx+si],al
00007D08 0000 add [bx+si],al
00007D0A 0000 add [bx+si],al
00007D0C 0000 add [bx+si],al
00007D0E 0000 add [bx+si],al
00007D10 0000 add [bx+si],al
00007D12 0000 add [bx+si],al
00007D14 0000 add [bx+si],al
00007D16 0000 add [bx+si],al
00007D18 0000 add [bx+si],al
00007D1A 0000 add [bx+si],al
00007D1C 0000 add [bx+si],al
00007D1E 0000 add [bx+si],al
00007D20 0000 add [bx+si],al
00007D22 0000 add [bx+si],al
00007D24 0000 add [bx+si],al
00007D26 0000 add [bx+si],al
00007D28 0000 add [bx+si],al
00007D2A 0000 add [bx+si],al
00007D2C 0000 add [bx+si],al
00007D2E 0000 add [bx+si],al
00007D30 0000 add [bx+si],al
00007D32 0000 add [bx+si],al
00007D34 0000 add [bx+si],al
00007D36 0000 add [bx+si],al
00007D38 0000 add [bx+si],al
00007D3A 0000 add [bx+si],al
00007D3C 0000 add [bx+si],al
00007D3E 0000 add [bx+si],al
00007D40 0000 add [bx+si],al
00007D42 0000 add [bx+si],al
00007D44 0000 add [bx+si],al
00007D46 0000 add [bx+si],al
00007D48 0000 add [bx+si],al
00007D4A 0000 add [bx+si],al
00007D4C 0000 add [bx+si],al
00007D4E 0000 add [bx+si],al
00007D50 0000 add [bx+si],al
00007D52 0000 add [bx+si],al
00007D54 0000 add [bx+si],al
00007D56 0000 add [bx+si],al
00007D58 0000 add [bx+si],al
00007D5A 0000 add [bx+si],al
00007D5C 0000 add [bx+si],al
00007D5E 0000 add [bx+si],al
00007D60 0000 add [bx+si],al
00007D62 0000 add [bx+si],al
00007D64 0000 add [bx+si],al
00007D66 0000 add [bx+si],al
00007D68 0000 add [bx+si],al
00007D6A 0000 add [bx+si],al
00007D6C 0000 add [bx+si],al
00007D6E 0000 add [bx+si],al
00007D70 0000 add [bx+si],al
00007D72 0000 add [bx+si],al
00007D74 0000 add [bx+si],al
00007D76 0000 add [bx+si],al
00007D78 0000 add [bx+si],al
00007D7A 0000 add [bx+si],al
00007D7C 0000 add [bx+si],al
00007D7E 0000 add [bx+si],al
00007D80 0000 add [bx+si],al
00007D82 0000 add [bx+si],al
00007D84 0000 add [bx+si],al
00007D86 0000 add [bx+si],al
00007D88 0000 add [bx+si],al
00007D8A 0000 add [bx+si],al
00007D8C 0000 add [bx+si],al
00007D8E 0000 add [bx+si],al
00007D90 0000 add [bx+si],al
00007D92 0000 add [bx+si],al
00007D94 0000 add [bx+si],al
00007D96 0000 add [bx+si],al
00007D98 0000 add [bx+si],al
00007D9A 0000 add [bx+si],al
00007D9C 0000 add [bx+si],al
00007D9E 0000 add [bx+si],al
00007DA0 0000 add [bx+si],al
00007DA2 0000 add [bx+si],al
00007DA4 0000 add [bx+si],al
00007DA6 0000 add [bx+si],al
00007DA8 0000 add [bx+si],al
00007DAA 0000 add [bx+si],al
00007DAC 0000 add [bx+si],al
00007DAE 0000 add [bx+si],al
00007DB0 0000 add [bx+si],al
00007DB2 0000 add [bx+si],al
00007DB4 0000 add [bx+si],al
00007DB6 0000 add [bx+si],al
00007DB8 0000 add [bx+si],al
00007DBA 0000 add [bx+si],al
00007DBC 0000 add [bx+si],al
00007DBE 0000 add [bx+si],al
00007DC0 0000 add [bx+si],al
00007DC2 0000 add [bx+si],al
00007DC4 0000 add [bx+si],al
00007DC6 0000 add [bx+si],al
00007DC8 0000 add [bx+si],al
00007DCA 0000 add [bx+si],al
00007DCC 0000 add [bx+si],al
00007DCE 0000 add [bx+si],al
00007DD0 0000 add [bx+si],al
00007DD2 0000 add [bx+si],al
00007DD4 0000 add [bx+si],al
00007DD6 0000 add [bx+si],al
00007DD8 0000 add [bx+si],al
00007DDA 0000 add [bx+si],al
00007DDC 0000 add [bx+si],al
00007DDE 0000 add [bx+si],al
00007DE0 0000 add [bx+si],al
00007DE2 0000 add [bx+si],al
00007DE4 0000 add [bx+si],al
00007DE6 0000 add [bx+si],al
00007DE8 0000 add [bx+si],al
00007DEA 0000 add [bx+si],al
00007DEC 0000 add [bx+si],al
00007DEE 0000 add [bx+si],al
00007DF0 0000 add [bx+si],al
00007DF2 0000 add [bx+si],al
00007DF4 0000 add [bx+si],al
00007DF6 0000 add [bx+si],al
00007DF8 0000 add [bx+si],al
00007DFA 0000 add [bx+si],al
00007DFC 0000 add [bx+si],al
00007DFE 55 push bp ; 引导扇区结束标志位1
00007DFF AA stosb ; 引导扇区结束标志位2
; ---8<--------------- [Cut Here] --------------->8--- ;
; .: keenjoy95 2007 :. ;
; .: keenjoy95_at_gmail_dot_com :. ;
; ! NO rights reserved ! ;
; ---------------------------------------------------- ;
[附 : 常见的 BIOS int 10号中断-13号功能调用的写法]
--------------------------------------------------
下面是代码片断,字符串 "Hello, MyOS world!" 具有统一的颜色熟悉0x0c(黑底浅红字)。
BootMessage:
db "Hello, MyOS world!" ; 待显示字符串信息
DisplayString:
mov ax, BootMessage ; 取字符串数据(段)的首地址
mov bp, ax ; ES:BP 赋值为待显示字符串的首地址 (BIOS INT 10h 定义参数)
mov cx, 18 ; CX 赋值为字符串长度(此处为固定值) (BIOS INT 10h 定义参数)
mov ax, 01301h ; AH 赋值为功能号13h(显示字符串) (BIOS INT 10h 定义参数)
; AL 输出模式参数赋值为01h (BIOS INT 10h 定义参数)
; ---------------------------------------------------
; 第 0 位 : 在输出之后更新光标位置
; 第 1 位 : 字符串包含交替的字符和属性
;
mov bx, 000ch ; BH 页号赋值为0 (BIOS INT 10h 定义参数)
; BL 属性赋值为黑底浅红字(属性字BL使用的前提为AL的高位置0)
; ---------------------------------------------------
; 16位色彩编码表 (D7 D6 D5 D4为背景色,D3 D2 D1 D0为前景色)
; ┏━━━━━━━━━━━┳━━━━━━━━━━━┓
; ┃ 0 0 0 0 黑 ┃ 1 0 0 0 灰 ┃
; ┃ 0 0 0 1 蓝 ┃ 1 0 0 1 浅蓝 ┃
; ┃ 0 0 1 0 绿 ┃ 1 0 1 0 浅绿 ┃
; ┃ 0 0 1 1 青 ┃ 1 0 1 1 浅青 ┃
; ┃ 0 1 0 0 红 ┃ 1 1 0 0 浅红 ┃
; ┃ 0 1 0 1 品红 ┃ 1 1 0 1 浅品红 ┃
; ┃ 0 1 1 0 棕 ┃ 1 1 1 0 黄 ┃
; ┃ 0 1 1 1 灰白 ┃ 1 1 1 1 白 ┃
; ┗━━━━━━━━━━━┻━━━━━━━━━━━┛
;
mov dx, 0000h ; DL 赋值为字符串显示的起始行 / 列号 (BIOS INT 10h 定义参数)
int 10h ; BIOS 10h号中断-13h号功能 (字符串屏显功能调用)
ret ; 子程序无参数返回
最后,祝各位前辈中秋快乐! ^_^
NUPT WANGyu