Assembly Bootloader 什么都不打印

Assembly Bootloader prints nothing at all

我正在尝试输出存储在我的引导扇区的 dx 寄存器中的十六进制值 program.It 在 all.NOT 甚至像往常一样在 Booting from Hard disk 什么也不输出。

我的代码:

boot_sect.asm

mov ah,0x0e ; TELE TYPE MODE
org 0x7c00 ;use when address of label is used
mov bx,HELLO
mov dx,0x1fb7
call print_bx
call print_dx

jmp $
%include "print_dx_hex.asm";function print_hex value in dx 
    
HELLO:
    db 'Hello World',0
times 510-($-$$) db 0
dw 0xaa55

print_dx_hex.asm

print_dx:
    pusha
    mov bx,HEX_OUT+5
    jmp INIT
CONT:
    dec bx
    shr dx,4
    cmp dx,0x0000
    jne INIT
    mov bx,HEX_OUT
    call print_bx
    popa 
    ret
INIT:
    mov ax,0x000f
    and ax,dx
    mov [bx],al
    jmp CONT

%include "print_bx.asm"

HEX_OUT:
    db "0x0000",0

print_bx.asm

print_bx:
    pusha
    call printing_loop
    mov al,0xa ; GOES TO
    int 0x10 ; NEW LINE
    mov al,0xd ; CARRIAGE
    int 0x10 ; RETURN
    popa
    ret
    
printing_loop:
    mov al,[bx]
    int 0x10
    add bx,0x01
    cmp byte [bx],0x00 ; LOOP TO ITERATE
    jne printing_loop ; THROUGH THE STRING
    ret

print_bx 完美运行(使用之前的代码测试)。

1)为什么代码不起作用?

2)为什么是完全空白而不是编译错误或错误值?

3)如何使用带有 qemu 的调试器自行查找错误?

您的代码遗漏了数字 0 到 15 与字符“0”到“9”和“A”到“F”之间的十六进制转换。

一个简单的解决方案是使用 XLATB 指令,该指令将 AL 寄存器中的值直接转换为内存中通过添加 BXAL 注册。

下面是您的程序的解决方案,不过有一些评论:

  • BIOS.Teletype 函数 0Eh 希望您在 BH 寄存器中传递所需的视频页面,如果视频模式是图形模式,甚至在 BL 寄存器中传递所需的颜色.因此,你不应该使用 BX 作为你的字符串指针。我使用 SI 作为字符串指针。
  • 您的引导加载程序使用 ORG 7C00h 指令并且应该根据 DS=0 设置 DS 段寄存器。您不能为此依赖 BIOS!
ORG 0x7C00

xor  ax, ax
mov  ds, ax
mov  si, HELLO
mov  dx, 0x1FB7
call print_si
call print_dx

jmp $

print_dx:
    pusha
    mov  bx, HEX_TABLE
    mov  si, HEX_OUT+5
    jmp  INIT
CONT:
    dec  si
    shr  dx, 4
    cmp  dx, 0
    jne  INIT
    mov  si, HEX_OUT
    call print_si
    popa 
    ret
INIT:
    mov  al, dl
    and  al, 15
    xlatb
    mov  [si], al
    jmp  CONT

HEX_OUT:
    db "0x0000", 0
HEX_TABLE:
    db "0123456789ABCDEF"

print_si:
    pusha
    mov  bx, 0x0007      ; VideoPage=0 Color=7 (White)
    mov  ah, 0x0E        ; BIOS.Teletype
    call printing_loop
    mov  al, 13
    int  0x10
    mov  al, 10
    int  0x10
    popa
    ret
    
printing_loop:
    mov  al, [si]
    int  0x10
    inc  si
    cmp  byte [si], 0
    jne  printing_loop
    ret

HELLO:
    db 'Hello World', 0
    times 510-($-$$) db 0
    dw 0xAA55

以上说明你的程序是正确的。我没有应用任何优化。如果您正在寻找技巧,post 您可以在 CodeReview 论坛上找到您的工作代码。