【发布时间】:2022-01-06 00:23:04
【问题描述】:
我有以下用 nasm 编写的引导扇区:
[org 0x7c00]
my_print_function:
mov ah, 0x0e
int 0x10
ret
_start:
mov al, 'A'
call my_print_function
call my_print_function
_boot:
jmp $
times 510-($-$$) db 0
dw 0xaa55
我用nasm -f bin boot.asm -o boot.bin 编译,然后运行qemu boot.bin,我只看到打印了一个字符,它是垃圾字符'U',而不是'A'。如果我更改my_print_function 和_start 的顺序,它会按预期工作,但子例程也会在没有我调用的情况下自行运行一次,因此它会打印'A' 3 次。
通常如果我正在编写程序集,我会在我的section .text 之前定义my_print_function,并在我的section .text 中添加一个global _start,但它似乎在这里没有任何作用。如何定义和使用这样的子例程,而不会因为我定义它而额外运行它?
【问题讨论】:
-
加载引导扇区的 BIOS 不知道您的
_start。它将控制权转移到物理地址0x7c00。所以你应该把你的主要放在那里。你可以把你的函数放在它后面。 -
是的,我意识到了这一点,但感谢您的评论!
-
另一种方法是将
jmp _start放在开头(地址0x7C00),然后将主代码放在您喜欢的任何位置。这在某些情况下是必要的(当存在“BIOS 参数块”时 - 请参阅en.wikipedia.org/wiki/BIOS_parameter_block) -
@Brendan 这也是一种聪明的做法!谢谢,将其添加到我的武器库中
-
您的第二段显示了关于如何组装成 ELF 目标文件的严重混淆。
.text是 NASM 源文件顶部的默认部分;如果您尚未切换到其他部分,section .text无效。global _start是相关的,因为它允许链接器在 ELF 元数据中看到该符号,默认情况下它正在寻找该符号。 IDK,如果您认为您的可执行机器代码不在.text部分内,则该 IDK 是 NASM 默认可执行的唯一部分:nasm.us/doc/nasmdoc8.html#section-8.9
标签: assembly nasm x86-16 bootloader subroutine