【问题标题】:int 10h 13h bios string output not workingint 10h 13h BIOS 字符串输出不工作
【发布时间】:2017-05-02 22:58:45
【问题描述】:

我正在使用 nasm,这是我的代码:

org 0x7c00
bits    16



section .data
 zeichen    dw  'hello2'
section .text


 mov ax,0x7c00
 mov    es,ax
 mov    bh,0
 mov    bp,zeichen

 mov    ah,13h
 mov    bl,00h
 mov    al,1
 mov    cx,6
 mov    dh,010h
 mov    dl,01h

int 10h

 jmp    $

 times  510 - ($-$$)    hlt
 dw 0xaa55

它确实将光标放在正确的位置,但它什么也没打印。 我用 qemu-system-i386 加载这个文件。 int10 ah=13h 是字符串输出,在寄存器 es:bp 中必须是字符串的地址

【问题讨论】:

  • 不止一个问题。您必须更好地理解段:偏移地址,但引导加载程序加载在物理地址 0x07c00。您必须选择一个与该地址相等的 ORG 和段。如果您选择 ORG 0x7c00,那么您需要将段(在这种情况下为 ES)设置为零,因为 (0x0000ES,这对于您选择的 ORG 不正确。
  • 其次,当使用-f bin NASM 输出时,您不想使用.data 部分。将数据放在代码之后但在引导签名之前的text部分内。如果您使用section data,NASM实际上会将您的数据放在引导扇区之外的字节512之后。
  • 您将 BL 设置为 0x00 。那是黑底黑字,所以不会出现输出。试试 0x07 吧?
  • 最后。我认为您的意思是使用db 而不是dw,因为您有一串字符。将zeichen dw 'hello2' 更改为zeichen db 'hello2'
  • 感谢您对其工作的帮助

标签: nasm x86-16 bootloader bios


【解决方案1】:

为了将来参考,因为我一直在努力让它工作很长时间,这里是一个工作版本!

    org 0x7c00
    bits 16

    xor ax, ax
    mov es, ax
    xor bh, bh
    mov bp, msg

    mov ah, 0x13
    mov bl, [foreground]
    mov al, 1
    mov cx, [msg_length]
    mov dh, [msg_y]
    mov dl, [msg_x]

    int 0x10

    hlt

foreground dw 0xa 
msg db 'Beep Boop Meow'
msg_length dw $-msg
msg_x dw 5
msg_y dw 2

    times  510 - ($-$$) db 0
    dw 0xaa55

这是最接近原版的版本。

    org 0x7c00
    bits 16

    ; video page number.
    mov bh, 0     
    ; ES:BP is the pointer to string.
    mov ax, 0x0
    mov es, ax    
    mov bp, msg   

    ; attribute(7 is light gray).
    mov bl, 0x7
    ; write mode: character only, cursor moved.
    mov al, 1
    ; string length, hardcoded.
    mov cx, 6
    ; y coordinate
    mov dh, 16
    ; x coordinate
    mov dl, 1

    ; int 10, 13
    mov ah, 0x13
    int 0x10

    ; keep jumping until shutdown.
    jmp $

msg dw  'hello2'

    times  510 - ($-$$) db 0
    dw 0xaa55

【讨论】:

  • msg_length dw $-msg - 通常您希望使用 EQU 常量作为立即数,而不是实际从内存中加载长度。
  • idk 但如果它仍然有效,它就可以满足我的目的,因为我绝对不记得这个了,我花了很多试验和错误来制作引导 iso 并在 virtualbox 中运行它们以确保我是诚实的。 :/ 但我敢肯定,也必须有某种方法可以用 equ 来做到这一点。在这个例子中,我想借此机会练习使用内存访问而不会使虚拟机崩溃。
  • 是的,它工作,但它是浪费空间。加载它的指令需要一个 2 字节的绝对地址,而它还不如直接使用 2 字节的立即数,例如 equ 中的 mov cx, msg_length。它不需要在运行时更改,因此您通常希望将其视为 C++ constexpr size_t len = sizeof(msg); 而不是 static size_t len = sizeof(msg);
猜你喜欢
  • 2019-09-05
  • 2016-03-02
  • 1970-01-01
  • 2016-10-30
  • 2016-03-04
  • 2019-05-15
  • 2020-04-12
  • 2020-02-22
  • 2012-01-31
相关资源
最近更新 更多