【问题标题】:Why doesn't this boot loader code work?为什么这个引导加载程序代码不起作用?
【发布时间】:2011-08-07 15:37:40
【问题描述】:

我的期望是它打印一个字符串,但什么都没有打印出来。 当我将字符串变短时,它有时会起作用,而当我再次将它们变长时,它有时会起作用。

我不知道为什么这不起作用。

有人可以帮我吗? 谢谢。

我使用的汇编代码是:

(Emacs 23、Ubuntu 10.10、nasm、VirtualBox OSE)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0x7c00
bits 16
str:
    db "Some say the world will end in fire",10,13
    db "Some say in ice",10,13
    db "From what I've tasted of desire",10,13
    db "I hold with those who favor fire",10,13
    db "But if I had to perish twice,",10,13
    db "I think I know enough of hate",10,13
    db "To say that for destruction ice",10,13
    db "is also great and would suffice."
    db "Robert Frost - Fire and Ice"
    db 0
start:
    xor ax,ax
    mov ds,ax
    mov es,ax
    mov si, str
    xor bx,bx
    mov ah, 0x0e
print:
    lodsb   ;al = current char
    cmp al, 0
    je end
    int 0x10
    jmp print
end:    
    cli
    hlt

    times 510 - ($-$$) db 0
    dw 0xAA55
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

【问题讨论】:

  • 我认为您需要添加一条 CLD 指令,以确保 lodsb 增加 si 而不会减少它。但是,我认为还有其他一些问题。

标签: assembly x86 nasm bootloader bios


【解决方案1】:

因为它在7c00 处的指令处开始执行代码。不幸的是,这就是你的字符串。

您应该在该字符串前面加上 jmp 指令,以便它跳转到 start

这通常是一个短跳转EB xx,然后是一个NOP 90。一些 BIOS 可能坚持这种形式,即使它对处理器来说并不重要。

换句话说,你会寻找类似的东西:

org 0x7c00
bits 16
realstart:
    jmp short start
    nop
str:
    db "Some say the world will end in fire",10,13
    :
    db "Robert Frost - Fire and Ice"
    db 0
start:
    xor  ax,ax
    :

请记住,短跳转受限于它可以走的距离,大约 +/-128 字节,因此您的字符串大小必然会受到限制。如果您的 BIOS 不需要 EB xx 90 格式,您可以进行常规跳转。

您可以尝试的另一件事是将整个字符串移动到 hlt 指令之后:

org 0x7c00
bits 16
start:
    xor  ax,ax
    :
end:    
    cli
    hlt
str:
    db "Some say the world will end in fire",10,13
    :
    db "Robert Frost - Fire and Ice"
    db 0

但是,同样,这取决于您的 BIOS 在开始时不需要 jmp/nop 组合。

【讨论】:

  • 谢谢。但我仍然想知道。你能解决我的问题吗=为什么即使字符串在 0x7c00 处“有时”也有效?
  • 可能某些字符串可以被解释为有效代码,最终执行“真实”代码。
【解决方案2】:

验证 paxdiablo 和 Igor Skochinsky 是否正确的一个好方法是将文本字符串放入文件中,然后通过反汇编程序运行它。正确打印的较短字符串应该反汇编成一个不会伤害任何东西的代码字符串。失败的较短字符串和较长的字符串将包含非法指令、跳转或调用指令,甚至在末尾有一个 2 或 3 字节的指令,它会在开头吃掉 "xor ax,ax" 指令的操作码你的代码。

【讨论】:

    猜你喜欢
    • 2012-12-21
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 2021-11-22
    • 2018-11-05
    • 2012-02-22
    • 2023-03-03
    • 2017-10-02
    相关资源
    最近更新 更多