assembly - 为什么这个引导加载程序代码不起作用?

标签 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

最佳答案

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

关于assembly - 为什么这个引导加载程序代码不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5699422/

相关文章:

linux - 使用 's-proc -e' 在 Linux (Fedora) hello.S 上执行汇编 shellcode 返回 SIGSEGV

c - 了解反汇编的 C 代码(特别是像 var_28 = dword ptr -28h 之类的东西)(二进制炸弹实验室)

c - while循环不写入显存

c++ - GCC 手册中提到的 "C++ ABI Specification"是什么?

assembly - 汇编中的函数结语

linux - 我不明白 "and ax, 1111111100000000b"指令在做什么

assembly - 如何在 nasm 中启用 a20?

assembly - arm7tdmi IRQ 和 FIQ 优先级

assembly - ASM 打印大数字

c++ - 对象在 assembly 级的x86中如何工作?