四個輸出消息的 NASM 彙編函數

    這兩天學寫操做系統進展不順,被卡住了!等搞清楚再繼續,就把調試的時候寫的幾個函數貼上來湊數吧。——win7下貌似沒有debug,有也不愛用,業餘屌絲仍是比較中意在代碼執行的時候直接輸出中間值來查錯。函數

    第一個函數是顯示字符串的:oop

; 功能:顯示緊跟在調用指令後定義的字符串
; 參數:無
; 反值:無
; 注意:本函數改變了寄存器 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 下一行定義字符串就行:spa

    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

  第三個是正常顯示字符串的:debug

; ----------------------------------------------------------------------------------------
; 函數功能:顯示字符串
; 入口參數: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
相關文章
相關標籤/搜索