簡體   English   中英

如何使用INT 10H顯示寄存器值

[英]How to display register value using INT 10H

我知道如果它的表示形式在AL中,我可以打印ASCII字符:

DrawChar:
  MOV AL, 0x45
  MOV AH, 0x0E
  MOV BL, 0x07
  MOV BH, 0x00
  INT 0x10
  RET

有什么方法可以使用INT 10H打印實際的寄存器值嗎? 像上面的示例中AL是0x45一樣,因此它將打印45(不必是十六進制表示)。 我正在16位實模式引導加載程序中執行此操作。

我會給你一種打印16位寄存器的方法。 通過將左16位寄存器的4位旋轉為最低有效位,然后隔離這4位,可以一次打印四位(4位)。 然后,我們打印該值的十六進制數字,該數字將是09AF 我們對16位字中的4個半字節中的每個半字節執行4次。

示例中提供了兩個 16位十六進制打印功能。 選擇一種適合您的環境:

  • print_hex_word可在任何8086/8088處理器或更高版本上使用。
  • print_hex_word是一個較小的版本,可在16位實模式下的任何80186/80188處理器上使用。

兩種變體都要求您:

  • 將一個2字節的值壓入包含頁碼和前景色的堆棧中(圖形模式)。 有關Int 10h / AH = 0eh的更多信息,請參見Ralf Brown的中斷列表。
  • 將2字節的值壓入要打印的堆棧上。

下面的示例代碼包含一個最小的引導程序作為示例:

bits 16
org 0x7c00

section .text
    global      _start

_start:
    ; Set segment registers to 0
    xor ax, ax
    mov ds, ax
    mov es, ax
    ; Set stack pointer just below bootloader
    mov ss, ax
    mov sp, 0x7c00
    ; Clear direction flag (forward movement)
    cld
    ; print_hex_word/print_hex_word_186 take a second parameter
    ; that is the page number (upper 8 bits) and foreground color
    ; in lower 8 bits. We just want 0x0000 so push it on the
    ; stack first
    push ax

    ; This test just prints SS and SP to the display
    push ss                 ; Push on stack as 1st parameter
                            ;    In this case display value in SS
    call print_hex_word     ; Print 16-bit value as hex
    add  sp, 2              ; Cleanup stack after call
    push sp                 ; Push on stack as 1st parameter
                            ;    In this case display value in SP
    call print_hex_word     ; Print 16-bit value as hex
    add  sp, 2              ; Cleanup stack after call

    ; Print value 0xaa55 to the display
    mov ax, 0xaa55
    push ax                 ; Push on stack as 1st parameter
                            ;    In this case display value in 0xAA55
    call print_hex_word     ; Print 16-bit value as hex

    cli                     ; Disable interrupts
    hlt                     ; Halt processor

; Print 16 bit value passed on stack as first parameter
; in hexadecimal. Use page number and foreground color
; passed in second parameter. This routine will work on 8086+
; processors. This code takes advantage of packed BCD to
; determine the ASCII values to print. This code could have
; used compare and branch to do the same or a translation table.

print_hex_word:
    push bp
    mov bp, sp      ; BP=SP, on 8086 can't use sp in memory operand
    push dx         ; Save all registers we clobber
    push cx
    push bx
    push ax

    mov cx, 0x0404  ; CH = number of nibbles to process = 4 (4*4=16 bits)
                    ; CL = Number of bits to rotate each iteration = 4 (a nibble)
    mov dx, [bp+4]  ; DX = word parameter on stack at [bp+4] to print
    mov bx, [bp+6]  ; BX = page / foreground attr is at [bp+6]

.loop:
    rol dx, cl      ; Roll 4 bits left. Lower nibble is value to print
    mov ax, 0x0e0f  ; AH=0E (BIOS tty print),AL=mask to get lower nibble
    and al, dl      ; AL=copy of lower nibble
    add al, 0x90    ; Work as if we are packed BCD
    daa             ; Decimal adjust after add.
                    ;    If nibble in AL was between 0 and 9, then CF=0 and
                    ;    AL=0x90 to 0x99
                    ;    If nibble in AL was between A and F, then CF=1 and
                    ;    AL=0x00 to 0x05
    adc al, 0x40    ; AL=0xD0 to 0xD9
                    ; or AL=0x41 to 0x46
    daa             ; AL=0x30 to 0x39 (ASCII '0' to '9')
                    ; or AL=0x41 to 0x46 (ASCII 'A' to 'F')
    int 0x10        ; Print ASCII character in AL
    dec ch
    jnz .loop       ; Go back if more nibbles to process

    pop ax          ; Restore registers
    pop bx
    pop cx
    pop dx
    pop bp
    ret

TIMES 510-($-$$) db 0
DW 0xaa55

該80186+版print_hex_word使用PUSHAPOPA保存和恢復寄存器AX,CX,DX,BX,獨創的SP,BP,SIDI:

; Print 16 bit value passed on stack as first parameter
; in hexadecimal. This routine will work on 80186+ processors
; Use page number and foreground color passed in second parameter

print_hex_word:
    pusha           ; Save all registers, 16 bytes total
    mov bp, sp      ; BP=SP, on 8086 can't use sp in memory operand
    mov cx, 0x0404  ; CH = number of nibbles to process = 4 (4*4=16 bits)
                    ; CL = Number of bits to rotate each iteration = 4 (a nibble)
    mov dx, [bp+18] ; DX = word parameter on stack at [bp+18] to print
    mov bx, [bp+20] ; BX = page / foreground attr is at [bp+20]

.loop:
    rol dx, cl      ; Roll 4 bits left. Lower nibble is value to print
    mov ax, 0x0e0f  ; AH=0E (BIOS tty print),AL=mask to get lower nibble
    and al, dl      ; AL=copy of lower nibble
    add al, 0x90    ; Work as if we are packed BCD
    daa             ; Decimal adjust after add.
                    ;    If nibble in AL was between 0 and 9, then CF=0 and
                    ;    AL=0x90 to 0x99
                    ;    If nibble in AL was between A and F, then CF=1 and
                    ;    AL=0x00 to 0x05
    adc al, 0x40    ; AL=0xD0 to 0xD9
                    ; or AL=0x41 to 0x46
    daa             ; AL=0x30 to 0x39 (ASCII '0' to '9')
                    ; or AL=0x41 to 0x46 (ASCII 'A' to 'F')
    int 0x10        ; Print ASCII character in AL
    dec ch
    jnz .loop       ; Go back if more nibbles to process
    popa            ; Restore all the registers
    ret

該代碼使用一些打包的二進制編碼的十進制(BCD)技巧將4位值轉換為十六進制數字。 有關打包BCD算術的更多信息,可以在本教程的“ 處理打包BCD編號 ”部分中找到。

要組裝此引導程序,可以使用:

nasm -f bin boot.asm -o boot.bin

可以使用QEMU在Linux命令行上對其進行測試,如下所示:

qemu-system-i386 -fda boot.bin

調試建議

如果您使用BOCHS ,則可以使用內置的調試器逐步調試自舉程序,並在代碼執行時顯示寄存器和內存的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM