我目前正在从头开始编写一个操作系统(制作自己的引导加载程序等),并且我正在尝试适应VESA模式。我已经读过文档了,它都是sense..all,但只做了几件事。
这直接来自文档(我有不同的实现方式):
vbe_set_mode:
mov [.width], ax
mov [.height], bx
mov [.bpp], cl
sti
push es ; some VESA BIOSes destroy ES, or so I read
mov ax, 0x4F00 ; get VBE BIOS info
mov di, vbe_info_block
int 0x10
pop es
cmp ax, 0x4F ; BIOS doesn't support VBE?
jne .error
mov ax, word[vbe_info_block.video_modes]
mov [.offset], ax
mov ax, word[vbe_info_block.video_modes+2]
mov [.segment], ax
mov ax, [.segment]
mov fs, ax
mov si, [.offset]
.find_mode:
mov dx, [fs:si]
add si, 2
mov [.offset], si
mov [.mode], dx
mov ax, 0
mov fs, ax
cmp [.mode], 0xFFFF ; end of list?
je .error
push es
mov ax, 0x4F01 ; get VBE mode info
mov cx, [.mode]
mov di, mode_info_block
int 0x10
pop es
cmp ax, 0x4F
jne .error
mov ax, [.width]
cmp ax, [mode_info_block.width]
jne .next_mode
mov ax, [.height]
cmp ax, [mode_info_block.height]
jne .next_mode
mov al, [.bpp]
cmp al, [mode_info_block.bpp]
jne .next_mode
; If we make it here, we've found the correct mode!
mov ax, [.width]
mov word[vbe_screen.width], ax
mov ax, [.height]
mov word[vbe_screen.height], ax
mov eax, [mode_info_block.framebuffer]
mov dword[vbe_screen.physical_buffer], eax
mov ax, [mode_info_block.pitch]
mov word[vbe_screen.bytes_per_line], ax
mov eax, 0
mov al, [.bpp]
mov byte[vbe_screen.bpp], al
shr eax, 3
mov dword[vbe_screen.bytes_per_pixel], eax
mov ax, [.width]
shr ax, 3
dec ax
mov word[vbe_screen.x_cur_max], ax
mov ax, [.height]
shr ax, 4
dec ax
mov word[vbe_screen.y_cur_max], ax
; Set the mode
push es
mov ax, 0x4F02
mov bx, [.mode]
or bx, 0x4000 ; enable LFB
mov di, 0 ; not sure if some BIOSes need this... anyway it doesn't hurt
int 0x10
pop es
cmp ax, 0x4F
jne .error
clc
ret
.next_mode:
mov ax, [.segment]
mov fs, ax
mov si, [.offset]
jmp .find_mode
.error:
stc
ret
.width dw 0
.height dw 0
.bpp db 0
.segment dw 0
.offset dw 0
.mode dw 0我搞不懂的是,为什么它把片段分配给视频模式指针加2?我知道视频模式指针有一个offset :段,但我只是搞不懂为什么我们将视频模式指针+2分配给段,以及为什么我们在将偏移量和段分配给dx寄存器后将si加2。
发布于 2021-11-23 18:06:44
mov ax,wordvbe_info_block.video_modes mov ax,wordvbe_info_block.video_modes+2 mov .offset,ax mov ax,wordvbe_info_block.video_modes+2 mov .segment,ax为什么要将数据段分配给视频模式指针加2?我知道视频模式指针有一个offset:段,但我只是搞不懂为什么我们将视频模式指针+2分配给该段
远指针存储在存储器中,具有字大小的偏移量,随后是字大小的段。
偏移量存储在vbe_info_block.video_modes中,段存储在地址多2的下一个字中,因此在[vbe_info_block.video_modes + 2]中
mov dx,fs:si add si,2 mov .offset,si,以及为什么我们在将偏移量和段分配给
dx寄存器后将si加2。
我们不将偏移量和段分配给 DX 寄存器!
我们检索到的(并放入FS:SI中的)远指针指向一个单词大小的模式数字列表。这是我们加载到DX寄存器中的模式编号。add si, 2 mov [.offset], si就在那里,所以循环可以遍历列表中的所有单词。
https://stackoverflow.com/questions/70084758
复制相似问题