这两天学写操作系统进展不顺,被卡住了!等搞清楚再继续,就把调试的时候写的几个函数贴上来凑数吧。——win7下貌似没有debug,有也不爱用,业余屌丝还是比较中意在代码执行的时候直接输出中间值来查错。
第一个函数是显示字符串的:
; 功能:显示紧跟在调用指令后定义的字符串 ; 参数:无 ; 反值:无 ; 注意:本函数改变了寄存器 ax、si 的值,如有必要,父函数应在调用前自行保存 PrintMsg: pop si ; si = IP mov ah, 0x0E ; 功能号,0x0E:显示一个字符,光标跟随字符移动 .Loop: lodsb cmp al, 0 ; 字符串以 0 结尾 je .Return int 0x10 jmp .Loop .Return: push si ; 恢复 ip ret
这个很好用,不用预先定义字符串,要用的时候直接在 call 下一行定义字符串就行:
call PrintMessage db "Message 1 !", `\r\n`, 0
第二个是显示数字的——把数字当字符串显示, 有了这个不用在 debug 里找变量中间值了!
; ---------------------------------------------------------------------------------------- ; 函数功能:以十六进制显示 32 位整数字符形式 ; 入口参数:eax = 数据 ; 出口参数:无 PrintHex: push bp mov bp, sp push edx push ecx push eax push dword 0 push dword ' ' ; 求余,把对应的数字转换成 ASCII 码,再压入栈 mov ecx, 16 .Rem: xor edx, edx div ecx cmp edx, 9 jg .Hex add edx, '0' ; 余数 0 - 9 转成 ASCII 码 jmp .Push .Hex: add edx, 'A' - 10 ; 余数 10 - 15 转成 ASCII 码 .Push: push edx cmp eax, 0 jnz .Rem push dword 'x' ; 16 进制数以 0x 前缀表示 push dword '0' mov ah, 0x0E .Print: pop ecx jcxz .Return mov al, cl int 0x10 jmp .Print .Return: pop eax pop ecx pop edx mov sp, bp pop bp ret
第三个是正常显示字符串的:
; ---------------------------------------------------------------------------------------- ; 函数功能:显示字符串 ; 入口参数:ds : si = 字符串地址 ; 出口参数:无 PrintStr: push bp mov bp, sp push ax push si mov ah, 0x0E ; 功能号,0x0E:显示一个字符,光标跟随字符移动 .Print: lodsb cmp al, 0 ; 字符串以 0 结尾 je .Return int 0x10 jmp .Print .Return: pop si pop ax mov sp, bp pop bp ret
; ---------------------------------------------------------------------------------------- ; 函数功能:直接写显存显示字符串 ; 入口参数:cl = 颜色属性 ; dh、dl = 屏幕行(0 ~ 24)、列坐标(0 ~ 79) ; ds : si = 待显示字符串地址 ; 出口参数:无 ; 80 * 25 彩色字模式的显存第一页(共 4 页)在内存中的地址为 B8000H ~ B8F9FH,向该地址写入 ; 内容将立即显示在屏幕上,共可显示 25 行、80 列,屏幕左上角为原点(0,0)。 ; 每个字符在显存中占两个字节,第一个字节是 ASCII 码,第二字节是颜色属性(共 256 种): ; 位: 7 6 5 4 3 2 1 0 ; 含义: BL R G B I R G B ; 闪烁 背景颜色 高亮 前景颜色 ShowStr: push bp mov bp, sp push es push di push si push dx push cx push ax mov ax, 0x0B800 mov es, ax ; 由行列坐标计算显存偏移量 mov al, 160 mul dh mov di, ax mov al, 2 mul dl add di, ax .Loop: mov al, [ds : si] cmp al, 0 jz .Return mov [es : di], al mov [es : di + 1], cl inc si add di, 2 jmp .Loop .Return: pop ax pop cx pop dx pop si pop di pop es mov sp, bp pop bp ret