我已经创建了一个字符串并将其转换为一个数组。循环遍历每个索引并移动到al寄存器,以便它可以打印到vga。问题是,它打印字符串的大小没有问题,但字符是乱七八糟的。你能帮我找出密码里的问题吗?我们会非常感激的。
org 0
bits 16
section .text
global _start
_start:
mov si, msg
loop:
inc si
mov ah, 0x0e
mov al, [si]
or al, al
jz end
mov bh, 0x00
int 0x10
jmp loop
end:
jmp .done
.done:
jmp $
msg db 'Hello, world!',0xa
len equ $ - msg
TIMES 510 - ($ - $$) db 0
DW 0xAA55引导加载程序代码
ORG 0x7c00
BITS 16
boot:
mov ah, 0x02
mov al, 0x01
mov ch, 0x00
mov cl, 0x02
mov dh, 0x00
mov dl, 0x00
mov bx, 0x1000
mov es, bx
int 0x13
jmp 0x1000:0x00
times 510 - ($ - $$) db 0
dw 0xAA55发布于 2022-10-08 16:11:18
引导加载器
在处理内核代码之前,让我们看一下引导加载器,它将内核带到内存中。
您已经编写了一个非常简约的引导加载程序版本,它省略了很多常见的内容,比如设置段寄存器,但是由于它的减少性质,这并不是一个问题。
可能是一个问题,是您编写了mov dl, 0x00,硬编码一个0来选择第一个软盘作为您的引导磁盘。如果确实是这样的话,没有问题,但是最好只使用BIOS预装DL寄存器的任何值。这是存放引导加载程序和内核的磁盘的ID。
是一个问题,是将内核加载到分段地址0x1000:0x1000,然后跳转到分段地址0x1000:0x0000,比内核少4096字节。幸运的是,内核代码最终确实运行了,这要归功于这两个地址之间的内存--很可能是由零字节填充的,这些字节(二次二)转换为指令add [bx+si], al。因为您忽略了DS段寄存器的设置,所以我们不知道有什么不幸的字节被覆盖了这么多次。希望这不是一个重要的字节..。
mov bx, 0x1000
mov es, bx
xor bx, bx <== You forgot to write this instruction!
int 0x13
jmp 0x1000:0x0000是一个问题,是,当从磁盘加载扇区时,您忽略了遇到故障的可能性。至少,您应该检查BIOS.ReadSector函数02h报告的进位标志,如果设置了标记,则可以彻底中止。更复杂的方法也会重试有限的次数,比如3次。
ORG 0x7C00
BITS 16
; IN (dl)
mov dh, 0x00 ; DL is bootdrive
mov cx, 0x0002
mov bx, 0x1000
mov es, bx
xor bx, bx
mov ax, 0x0201 ; BIOS.ReadSector
int 0x13 ; -> AH CF
jc ERR
jmp 0x1000:0x0000
ERR:
cli
hlt
jmp ERR
times 510 - ($ - $$) db 0
dw 0xAA55内核
在jmp 0x1000:0x0000指令将您带到内核的第一条指令之后,CS代码段寄存器保存的值为0x1000。其他的段寄存器都没有改变,而且由于您没有在引导加载器中设置它们中的任何一个,所以我们仍然不知道它们中包含了什么。但是,为了用mov al, [si]指令从msg上的消息中检索字节,我们需要DS数据段寄存器的正确值。根据ORG 0指令,正确的值是我们在CS中已经拥有的值。只需要两个1字节的指令:push cs pop ds.
关于内核代码还有更多的内容要说:
mov si, msg - 1.times生成的大量零字节。在未来的代码版本中,可能根本没有零字节!0xa)。对于BIOS.Teletype函数0Eh,这只是一个在屏幕上向下移动的行提要。要获得换行符,您需要同时包含回车(13)和linefeed (10).times 512 - ($ - $$) db 0.内核:
ORG 0
BITS 16
section .text
global _start
_start:
push cs
pop ds
mov si, msg
mov bx, 0x0007 ; DisplayPage=0, GraphicsColor=7 (White)
jmp BeginLoop
PrintLoop:
mov ah, 0x0E ; BIOS.Teletype
int 0x10
BeginLoop:
mov al, [si]
inc si
test al, al
jnz PrintLoop
cli
hlt
jmp $-2
msg db 'Hello, world!', 13, 10, 0
TIMES 512 - ($ - $$) db 0https://stackoverflow.com/questions/73962758
复制相似问题