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

发布于 2024-11-02 04:02:16 字数 985 浏览 1 评论 0原文

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

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

有人可以帮助我吗? 谢谢。

我使用的汇编代码是:

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

My expectation is that it prints a string, but nothing is printed out.
When I make the string shorter, it sometimes works, and when I make them longer again, it works sometimes.

I don't know why this isn't working.

Could somebody help me?
Thanks.

The assembly code I'm using is:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

草莓味的萝莉 2024-11-09 04:02:16

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

Because it starts executing code right at the instruction at 7c00. That, unfortunately is where you have your string.

You should precede that string with a jmp instruction so that it jumps to start.

This is usually a short jump EB xx followed by a NOP 90. Some BIOS' may insist on that being of this form even though it doesn't really matter to the processor.

In other words, you'd be looking for something like:

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
    :

Just keep in mind that the short jump is limited as to what distance it can go, roughly +/-128 bytes, so your string size will be necessarily limited by that. If your BIOS doesn't require the EB xx 90 format, you can just do a regular jump.

The other thing you could try is to move the entire string to after the hlt instruction:

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

but, again, this depends on your BIOS not requiring the jmp/nop combo at the start.

澜川若宁 2024-11-09 04:02:16

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

A good way to verify that paxdiablo and Igor Skochinsky are correct is to put the text string in a file, then run it thorough a disassembler. The shorter strings that print properly should disassemble into a code string that doesn't hurt anything. The shorter strings that fail, and the longer string will either include illegal instructions, jump or call instructions, or even just have a 2- or 3-byte instruction at the end that eats up the opcode for the "xor ax,ax" instruction at the beginning of your code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文