【问题标题】:print string with bios interrupt 0x10打印带有 BIOS 中断 0x10 的字符串
【发布时间】:2015-02-04 14:09:24
【问题描述】:

我想使用 bios 中断 0x10 打印一个字符串。但我只得到一个蓝色字段,其中没有字母。也许我通过处理我的字符串来解决问题。

编辑:我有两个代码文件。第一个写入软盘的第一个扇区。它将第二个扇区从软盘复制到内存(从 0x5000 开始)并跳转到 0x5000。这是我的第二个文件,我应该在其中打印我的字符串。

[BITS 16]
org 0x5000

sect2:
    mov ah, 0x03    ;get curser position
    mov bh, 0x00    ;page number

    int 0x10

    mov ax, 0x0500 
    mov es, ax
    mov bp, bsy1msg 

    mov ah, 0x13            ;write string
    mov al, 0x01            ;update cursor after writing
    mov bh, 0x00            ;page number
    mov bl, 0x1F            ;atributes
    mov cx, bsy1len         ;number of characters in string

    int 0x10

end:
    jmp end

bsy1msg db 13,10,"BSY1 via INT 0x10"
bsylen equ $ - bsy1msg

【问题讨论】:

  • 尝试使用 mov ax,cs 而不是那个常量来加载 ES。我不完全相信你的假设是有效的。
  • 使用 'mov ax, cs' 我得到相同的结果
  • 可能是 'org 0x5000' ?
  • 确定 DH/DL(行/列)具有合理的值吗?

标签: assembly nasm x86-16 bios


【解决方案1】:

org 指令不会将程序加载到特定的物理地址,它会通知汇编器假设程序已加载到代码段的那么远。

例如,sect2 的值不为零,而是0x5000

es 设置为0x500 会使其从物理地址05000 开始,但这不是程序所在的位置。您希望额外的段与代码段在同一点开始,因为bsy1msg 标签是相对于代码段的(如果我计算正确,它的值是0x501d)。

push cs
pop es

【讨论】:

  • 我的程序在 0x5000。作为一个初学者,我忘了把这个添加到我的问题中。
  • @spitzbuaamy:那么es 仍应与cs 相同,即为零。
【解决方案2】:

地址表示为segment:offset,物理地址计算为segment*16+offset。所以0x0500:0 指的是与0:0x5000 相同的物理地址。如果您的程序位于物理地址 0x5000,那么 CS:IP 应该是 0x0500:00:0x5000。该字符串位于物理地址 0x501d。由于您指定org 0x5000,nasm 将假定 bsy1msg 的偏移量为 0x501d。这意味着该段必须为 0 (0*16+0x501d = 0x501d)。或者,如果您将 ES 设置为 0x0500(直接或通过复制 CS),则需要省略 org 0x5000 或从 BP 中减去偏移量 (mov bp,bsy1msg-sect2) 以获得正确的物理地址 (0x0500*16+0x001d = 0x501d)。

【讨论】:

    猜你喜欢
    • 2021-11-21
    • 2013-06-22
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2013-02-26
    • 1970-01-01
    相关资源
    最近更新 更多