我在装配编程中已经3-4天了。试图在视频内存中打印一个字符串并通过qemu运行。 我希望这个程序可以打印Hallo世界。但它什么都不打印。 qemu窗口打印"从硬盘启动......"没有别的
引导加载程序中只允许16位吗?在那种情况下,我将如何做MMIO?我正在关注http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf的实际第32页[输入32位受保护模式]
[bits 32]
[org 0x7c00]
loop:
mov edx, 0xb8000
mov ah, 0x0f
mov ebx, message
mov ecx, 0x0
call draw_string
;jmp self_loop
;jmp loop
self_loop:
jmp self_loop
; take the stream begining from ebx
draw_string:
mov al, [ebx]
mov ah, 0x0f
mov [edx], ax
add ebx, 1
add edx, 2
cmp al, 0
jne draw_string
ret
message:
db 'Hallo World', 0x0
times 510 -( $ - $$ ) db 0 ; When compiled , our program must fit into 512 bytes ,
; with the last two bytes being the magic number ,
; so here, tell our assembly compiler to pad out our
; program with enough zero bytes (db 0) to bring us to the
; 510th byte.
dw 0xAA55 ; Last two bytes (one word) form the magic number ,
; so BIOS knows we are a boot sector.
答案 0 :(得分:1)
CPU启动时16位实模式分段寻址的示例,其中默认段大小限制为64 KB。在实模式中,我们可以使用32位偏移寄存器(80386+),但是偏移地址必须指向64 KB大小的段限制,并且不能指向64 KB段大小之外的地址。 (因为我们不需要32位偏移寄存器来访问0到FFFF之间的偏移量,所以我在本例中使用16位偏移寄存器。)为了访问超过64 KB,我们可以使用其他段寄存器和/或我们可以将其他段地址存储到段寄存器中。
...
因为hello world消息的字节放在代码段中,所以我们希望为数据段寄存器使用相同的段地址,以获取消息的每个字节。
mov ax,cs
mov ds,ax
现在我们将textmode视频缓冲区的段地址存储在额外的段寄存器中。
mov ax,0xb800 ; = this is a segment address and not a linear offset address
mov es,ax
lea bx,message ; Now we get the source address in BX
mov di,0x0 ; and the target address for output (upper left corner) in DI
call draw_string
self_loop:
jmp self_loop
; take the stream begining from DS:bx
draw_string:
mov al,[bx] ; load a byte from the address of DS:BX
mov ah,0x0f
mov es:[di],ax ; store a word to the address of ES:DI
add bx,1
add di,2 ; increasing the target offset address
cmp al,0
jne draw_string
ret