为什么这个启动加载程序代码不起作用?

时间:2011-04-18 06:49:29

标签: assembly x86 nasm bootloader bios

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

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

有人能帮帮我吗? 感谢。

我正在使用的汇编代码是:

(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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

2 个答案:

答案 0 :(得分:9)

因为它在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组合。

答案 1 :(得分:1)

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

相关问题