**请注意,当我说启动程序时,我并不是指启动操作系统的程序。我的意思是,当你启动计算机并执行某些操作时运行的简单程序。
好吧,所以我不是非常精通Assembly / NASM,但我认为我已经掌握了很好的知识来编写简单的启动程序。
好吧,我思考我已经掌握了足够的知识。显然不是。
我尝试了一个我在网上找到的简单启动程序。它运行良好(打印字母'A')。然后我修改它以打印存储在内存中的字母。它失败了;而不是打印'A',它打印出一个笑脸。 (我发誓,电脑现在正嘲笑我。)
这是源文件中的代码:
[BITS 16] ; We start up in 16-bit real mode
[ORG 0x7C00] ; We're booted into memory at this address. (Or so I'm told)
mov ah, 0x0E ; Teletype command
mov bh, 0x00 ; Page number
mov bl, 0x07 ; Attributes (7 == white foreground, black background)
mov al, [testChar] ; Character to print; load it from the memory referenced by testChar.
int 0x10 ; Tell the BIOS to execute the teletype command.
jmp $ ; Infinite loop prevents us from going off and executing the other junk in memory
testChar db 65 ; This is the character we want to print. 'A'.
; The following code pads the rest of the outputted binary file
; and concludes it with the bootloader signature so I don't have
; to do so manually.
times 510-($-$$) db 0
dw 0xAA55
如果我用“移动al,65 ”替换“移动al,[testChar] ”,则会正确打印字母“A”。我试过移动内存声明,我尝试了BITS和ORG周围的括号或括号的每个组合,我尝试递增和递减testChar(即[testChar + 1])。每次打印时都会显示一个笑脸,一个反向笑脸(当我增加testChar时),或者什么都没有(当我在代码之前放入内存声明时,可能是因为没有执行代码= P)。我无法得到该死的东西。
现在,对于规范(因为它们可能相关):
我正在使用英特尔奔腾II处理器运行戴尔Latitude CPi,因为这是我必须测试的所有内容(我没有使用普通计算机测试汇编程序。没有。)。我很确定说处理器是x86,因为我在它上面运行Windows XP,Ubuntu和Arch Linux。
我目前正在使用NASM在Arch Linux上编写和编译程序。
启动程序从软盘运行
我使用' nasm -f bin FILENAME '来编译代码。
然后我使用'mtools'软件包中的'mformat'命令将AL通过' mformat -f 1440 -B BOOTPROGRAM A:将编译后的引导程序传输到软盘上/ EM> ”。
那么,这次搞砸了什么?或者我的处理器/ BIOS有问题吗?
答案 0 :(得分:3)
DS可能充满了一些垃圾值,所以只需:
push cs
pop ds
或
mov ax, cs
mov ds, ax
mov es, ax
更好的是,不要相信CS并且做:
xor ax, ax
mov ds, ax
请参阅this discussion:某些BIOS可能使用07c0:0000而不是传统的0000:7c00,特别是在使用ElTorito从CD-ROM启动时。
答案 1 :(得分:0)
这产生了以下代码(只需在编译的代码上运行objdump)。
00000000 B40E mov ah,0xe
00000002 B700 mov bh,0x0
00000004 B307 mov bl,0x7
00000006 A00D7C mov al,[0x7c0d]
00000009 CD10 int 0x10
0000000B EBFE jmp short 0xb
0000000D 41 inc cx ; this is actually your testChar
; ignore the opcode translation
现在,如果你位于0x7C00,那么[0x7c0d]将是其中的最后一个字节(即0x41或65,或ASCII“A”)。但是,如果像其他贡献者之一(ninjalj)提到你有一些奇怪的BIOS错误,这意味着你不在0x7C00,那么[0x7c0d]是任何人的猜测。
答案 2 :(得分:0)
我第一次跑的时候运行得很好!它打印'A'。使用命令nasm [filename.asm] -o [filename.com] -l [filename.lst]
我使用了nasm OSbad.asm -o OSbad.com。使用MagicISO制作可启动映像文件OSbad.iso并使用Windows磁盘刻录机将其刻录到DVD / RW。加载了Oracle VM并制造了一个新的虚拟机,具有256 Mb RAM,CD / DVD,2GB硬盘。用DVD启动,然后在屏幕上打印“A”。
所以我猜你的程序正在运行。必须是你正在做的其他事情使它无法正常工作。