四个输出消息的 NASM 汇编函数

    这两天学写操作系统进展不顺,被卡住了!等搞清楚再继续,就把调试的时候写的几个函数贴上来凑数吧。——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


你可能感兴趣的:(四个输出消息的 NASM 汇编函数)