hehongjie
User
 Fresh Osdever
| Posts: 1 |   | Karma: 0
|
VBE Function issue - 2007/10/11 00:13
I call the VBE AX=0X4f00 function,computer always reboot.
My VGA card hardware is Intel845G,below code write in nasm compiler.
Thank.
; 按照.exe文件的建构来构建 org 0x100000 ; 指定代码开始位置 bits 32
exehead times 0x100 db 0x0
main: jmp main_variable_end main_eip dd 0x0 ; 临时保存的堆栈数据 main_parametersize dd 0x03 ; 参数个数 main_returnvalueaddress dd 0X03 ; 返回值地址 main_gdtbase dd 0X03 ; GDT表基址 mian_diskbuffer times 4096 db 0x0 mian_vesabiosimg times 65536 db 0x0 main_srcmempoint dd 0x0 main_destmempoint dd 0x0 mian_i dd 0x0 main_diskpoint dd 0x20000 ; 将显卡信息写入磁盘的位置(扇区号),写入位置为文件之外,测试用。 mian_addrpminfoblock dd 0x0 ; pminfoblock的位置指针 mian_vbestack times 1024 db 0x0 ; pminfoblock的位置指针 main_ldt dw 0x0 ; ldt内容 main_biosdatasel times 0x0600 db 0x0 ; vbe3的缓冲区 mian_farcall times 6 db 0x0; 段间调用地址 ; ss esp的保存位置 main_ss dw 0x0 main_esp dd 0x0 main_es dw 0x0 ldt_start: dw 0 dw 0 dw 0 dw 0
dw 0 dw 0 dw 0 dw 0
dw 0 dw 0 dw 0 dw 0
dw 0 dw 0 dw 0 dw 0
dw 0 dw 0 dw 0 dw 0
dw 0 dw 0 dw 0 dw 0
dw 0 dw 0 dw 0 dw 0
dw 0 dw 0 dw 0 dw 0
dw 0 ; 测试用ldt dw 0 dw 0 dw 0
ldt_end:
; VBE 变量 vbereturnstatus dw 0x0000 vbecontrollerinfomation times 512 db 0x0
main_variable_end: ; 通过堆栈传递n个参数,每个参数固定4字节,栈底为参数个数(包括“参数个
”参数)和返回值地址(如果返回值地址为0表示不需要返回置),即“参
个数”参数最少为2) ; 参数压栈顺序从右到左,弹出顺序从左到右 pop dword [main_eip]
pop dword [main_parametersize] pop dword [main_returnvalueaddress] pop dword [main_gdtbase]
push dword [main_eip]
mov dword [main_srcmempoint],0xC0000 mov dword [main_destmempoint],mian_vesabiosimg mov dword [mian_i],0x0 cld main_for_1: mov ecx,1024 mov esi,dword [main_srcmempoint] mov edi,dword [main_destmempoint] rep movsd ; 保存到磁盘 ;push dword [main_srcmempoint] ;push dword [main_diskpoint] ;push 0x00 ;push 0x04 ;call writedisk ;add dword [main_diskpoint],0x08
add dword [main_srcmempoint],0x1000 add dword [main_destmempoint],0x1000 inc dword [mian_i] cmp dword [mian_i],16 jnz main_for_1
; 定位 mian_addrpminfoblock mov dword [mian_addrpminfoblock],mian_vesabiosimg + 0x00004F70
; 设置ldt在gdt中的描述符 mov ebx,dword [main_gdtbase] mov word [ebx + 0x18 + 0],ldt_end - ldt_start - 1 mov edx,ldt_start mov word [ebx + 0x18 + 2],dx shr edx,16 mov byte [ebx + 0x18 + 4],dl mov byte [ebx + 0x18 + 5],0x82 ; 8X 为系统描述符 mov byte [ebx + 0x18 + 6],0x40 mov byte [ebx + 0x18 + 7],dh ; 设置ldt的内容(biosdatasel) mov ebx,ldt_start mov word [ebx + 0x0 + 0],0x0600 - 1 mov edx,main_biosdatasel mov word [ebx + 0x0 + 2],dx shr edx,16 mov byte [ebx + 0x0 + 4],dl mov byte [ebx + 0x0 + 5],0x92 mov byte [ebx + 0x0 + 6],0x00 mov byte [ebx + 0x0 + 7],dh
; 设置ldt的内容(A0000H) mov ebx,ldt_start mov word [ebx + 0x08 + 0],0xFFFF mov edx,0x000A0000 mov word [ebx + 0x08 + 2],dx shr edx,16 mov byte [ebx + 0x08 + 4],dl mov byte [ebx + 0x08 + 5],0x92 mov byte [ebx + 0x08 + 6],0x00 mov byte [ebx + 0x08 + 7],dh
; 设置ldt的内容(B0000H) mov ebx,ldt_start mov word [ebx + 0x10 + 0],0xFFFF mov edx,0x000B0000 mov word [ebx + 0x10 + 2],dx shr edx,16 mov byte [ebx + 0x10 + 4],dl mov byte [ebx + 0x10 + 5],0x92 mov byte [ebx + 0x10 + 6],0x00 mov byte [ebx + 0x10 + 7],dh
; 设置ldt的内容(B8000H) mov ebx,ldt_start mov word [ebx + 0x18 + 0],0x7FFF mov edx,0x000B8000 mov word [ebx + 0x18 + 2],dx shr edx,16 mov byte [ebx + 0x18 + 4],dl mov byte [ebx + 0x18 + 5],0x92 mov byte [ebx + 0x18 + 6],0x00 mov byte [ebx + 0x18 + 7],dh
; 设置ldt的内容(CodeSegSel) mov ebx,ldt_start mov word [ebx + 0x20 + 0],0xFFFF mov edx,mian_vesabiosimg mov word [ebx + 0x20 + 2],dx shr edx,16 mov byte [ebx + 0x20 + 4],dl mov byte [ebx + 0x20 + 5],0x92 mov byte [ebx + 0x20 + 6],0x00 mov byte [ebx + 0x20 + 7],dh
; 设置保护模式标记 mov ebx,dword [mian_addrpminfoblock] add ebx,18 mov byte [ebx],0x01 ; 设置ldt的内容(保护模式BIOS缓冲,可执行的) mov ebx,ldt_start mov word [ebx + 0x28 + 0],0xFFFF mov edx,mian_vesabiosimg mov word [ebx + 0x28 + 2],dx shr edx,16 mov byte [ebx + 0x28 + 4],dl mov byte [ebx + 0x28 + 5],0x9A mov byte [ebx + 0x28 + 6],0x00 mov byte [ebx + 0x28 + 7],dh
; 设置ldt的内容(VBE 16Bit Stack) mov ebx,ldt_start mov word [ebx + 0x30 + 0],1024 - 1 mov edx,mian_vbestack mov word [ebx + 0x30 + 2],dx shr edx,16 mov byte [ebx + 0x30 + 4],dl mov byte [ebx + 0x30 + 5],0x92 mov byte [ebx + 0x30 + 6],0x00 mov byte [ebx + 0x30 + 7],dh
; 设置ldt的内容(512字节的VBE Info缓冲区) mov ebx,ldt_start mov word [ebx + 0x38 + 0],0x01FF mov edx,vbecontrollerinfomation mov word [ebx + 0x38 + 2],dx shr edx,16 mov byte [ebx + 0x38 + 4],dl mov byte [ebx + 0x38 + 5],0x92 mov byte [ebx + 0x38 + 6],0x00 mov byte [ebx + 0x38 + 7],dh
; 设置ldt的内容(测试段1M,起始地址0x100000内容为core.asm,可执行的) mov ebx,ldt_start mov word [ebx + 0x40 + 0],0xFFFF mov edx,0x100000 mov word [ebx + 0x40 + 2],dx shr edx,16 mov byte [ebx + 0x40 + 4],dl mov byte [ebx + 0x40 + 5],0x9A mov byte [ebx + 0x40 + 6],0x0F ; 0x4F mov byte [ebx + 0x40 + 7],dh
; 设置 VBE Bios 缓冲 mov ebx,dword [mian_addrpminfoblock] mov word [ebx + 8],0x0004 mov word [ebx + 10],0x000C mov word [ebx + 12],0x0014 mov word [ebx + 14],0x001C mov word [ebx + 16],0x0024
; 设置 check sum mov ebx,dword [mian_addrpminfoblock] mov al,0x00 add al,byte [ebx + 0] add al,byte [ebx + 1] add al,byte [ebx + 2] add al,byte [ebx + 3] add al,byte [ebx + 4] add al,byte [ebx + 5] add al,byte [ebx + 6] add al,byte [ebx + 7] add al,byte [ebx + 8] add al,byte [ebx + 9] add al,byte [ebx + 10] add al,byte [ebx + 11] add al,byte [ebx + 12] add al,byte [ebx + 13] add al,byte [ebx + 14] add al,byte [ebx + 15] add al,byte [ebx + 16] add al,byte [ebx + 17] add al,byte [ebx + 18] mov ah,255 sub ah,al inc ah mov byte [ebx + 19],ah
; 设置 装载ldt main_ldt mov word [main_ldt],0x0018 lldt word [main_ldt]
mov word [main_ss],ss ; 保存堆栈寄存器 mov dword [main_esp],esp mov word [main_es],es
mov dx,0x0034 mov ss,dx mov esp,1024
mov ax,0x4F00 mov dx,0x003C mov es,dx mov di,0x00
mov ebx,testcall sub ebx,0x100000 mov dword [mian_farcall + 0],ebx mov word [mian_farcall + 4],0x0044 call dword far [mian_farcall]
mov dx,word [main_ss] mov ss,dx mov edx,dword [main_esp] mov esp,edx mov dx,word [main_es] mov es,dx ; 恢复堆栈寄存器
push mian_diskbuffer push 0x08 push 0x00 push 0x04 call writedisk
ret
; 调用VBE初始化入口 mov word [main_ss],ss ; 保存堆栈寄存器 mov dword [main_esp],esp mov word [main_es],es mov dx,0x0034 mov ss,dx mov esp,1024 mov ax,0x4F00 mov dx,0x003C mov es,dx mov di,0x00
mov edx,dword [mian_addrpminfoblock] add edx,6 mov ebx,0x0 mov bx,word [edx] mov dword [mian_farcall + 0],ebx mov word [mian_farcall + 4],0x002C call dword far [mian_farcall]
mov dx,word [main_ss] mov ss,dx mov edx,dword [main_esp] mov esp,edx mov dx,word [main_es] mov es,dx ; 恢复堆栈寄存器
;mov dword[mian_diskbuffer],0x88664444
;push mian_diskbuffer ;push 0x08 ;push 0x00 ;push 0x04 ;call writedisk
; 调用一个VBE函数 mov word [main_ss],ss ; 保存堆栈寄存器 mov dword [main_esp],esp mov word [main_es],es mov dx,0x0034 mov ss,dx mov esp,1024 mov ax,0x4F00 mov dx,0x003C mov es,dx mov di,0x00
mov edx,dword [mian_addrpminfoblock] add edx,4 mov ebx,0x0 mov bx,word [edx] mov dword [mian_farcall + 0],ebx mov word [mian_farcall + 4],0x002C call dword far [mian_farcall]
mov dx,word [main_ss] mov ss,dx mov edx,dword [main_esp] mov esp,edx mov dx,word [main_es] mov es,dx ; 恢复堆栈寄存器
;mov ecx,128 ;mov esi,vbecontrollerinfomation ;mov edi,mian_diskbuffer ;rep movsd
;mov ebx,dword [mian_addrpminfoblock] ;mov edx,dword [ebx + 0] ;mov dword [mian_diskbuffer + 0],edx ;mov edx,dword [ebx + 4] ;mov dword [mian_diskbuffer + 4],edx ;mov edx,dword [ebx + 8] ;mov dword [mian_diskbuffer + 8],edx ;mov edx,dword [ebx + 12] ;mov dword [mian_diskbuffer + 12],edx ;mov edx,dword [ebx + 16] ;mov dword [mian_diskbuffer + 16],edx
mov dword [mian_diskbuffer + 512 + 8],0xAABBEEF1 mov dword [mian_diskbuffer + 512 + 12],0xCCDDAAB2 push mian_diskbuffer push 0x08 push 0x00 push 0x04 call writedisk
ret ; 读磁盘(4K字节) ; 返回值 int returnvalue ,1表示操作成功,0表示操作失败 ; 输入参数 int clusternum ,要读取的扇区号,8的整数倍 ; 输入参数 int* mempoint ,读取内容的存放位置(占用4K字节) readdisk: jmp readdisk_variable_end readdisk_eip dd 0x0 ; 临时保存的堆栈数据
readdisk_parametersize dd 0X0 readdisk_returnvalueaddress dd 0X0 readdisk_clusternum dd 0X08 readdisk_mempoint dd 0X0 readdisk_variable_end:
pop dword [readdisk_eip]
pop dword [readdisk_parametersize] pop dword [readdisk_returnvalueaddress] pop dword [readdisk_clusternum] pop dword [readdisk_mempoint]
push dword [readdisk_eip]
cmp dword [readdisk_returnvalueaddress],0x0 je readdisk_retuen_none mov ebx,dword [readdisk_returnvalueaddress] mov dword [ebx],0X01 readdisk_retuen_none: MOV DX, 1F7h ;status register readdisk_LOOP1: IN AL,DX ;sets AL to status register (which is 8 bits) AND AL, 10000000B JNE readdisk_LOOP1 MOV DX, 1F7h ;status register again readdisk_LOOP2: IN AL, DX ;sets AL to status register again AND AL, 01000000B JE readdisk_LOOP2 ; 设置不使用中断 ;3F6 (Read): Alternate Status Register ;3F6 (Write): Device Control Register mov dx,3F6H mov al,02H out dx,al ; 设置扇区数 8扇区 4KBytes mov dx,1F2H mov al,08H out dx,al ; 设置lba地址数据 ;1F3H (Read and Write): LBA Low Register ;1F4H (Read and Write): LBA Mid Register ;1F5H (Read and Write): LBA High Register
mov dx,1F3H mov al,byte [readdisk_clusternum + 0] out dx,al mov dx,1F4H mov al,byte [readdisk_clusternum + 1] out dx,al mov dx,1F5H mov al,byte [readdisk_clusternum + 2] out dx,al ; 设置磁盘和模式 MOV DX, 1F6H ;device/head register MOV AL, 40H ;0 selects device 0 (master). 10h would select device 1 (slave). 40表示lba模式 OUT DX, AL ;selects master device MOV DX, 1F7H ;command register MOV AL, 20H ; OPCODE - 20h (with retries) or 21h (without retries) OUT DX, AL ; sends the command! MOV DX, 1F7H ;status register readdisk_LOOP3: IN AL, DX AND AL, 00001000B ;if DRQ is not high, the device doesn't have data for us JE readdisk_LOOP3 ;yet, so keep looking until it does! MOV DX, 1F0H ;data register MOV edi, dword [readdisk_mempoint] ;points DI to the buffer we're using MOV ecx, 2048 ; 2048 decimal. This controls the REP command. 4K Bytes writeing. CLD ;clear the direction flag so INSW increments DI (not decrements it) REP insw ret
; 写磁盘(4K字节) ; 返回值 int returnvalue ,1表示操作成功,0表示操作失败 ; 输入参数 int clusternum ,要写入的扇区号,8的整数倍 ; 输入参数 int* mempoint ,写入内容的存放位置(占用4K字节) writedisk: jmp writedisk_variable_end writedisk_eip dd 0x0 ; 临时保存的堆栈数据
writedisk_parametersize dd 0X0 writedisk_returnvalueaddress dd 0X0 writedisk_clusternum dd 0X08 writedisk_mempoint dd 0X0 writedisk_variable_end:
pop dword [writedisk_eip]
pop dword [writedisk_parametersize] pop dword [writedisk_returnvalueaddress] pop dword [writedisk_clusternum] pop dword [writedisk_mempoint]
push dword [writedisk_eip]
cmp dword [writedisk_returnvalueaddress],0x0 je writedisk_retuen_none mov ebx,dword [writedisk_returnvalueaddress] mov dword [ebx],0X01 writedisk_retuen_none: MOV DX, 1F7h ;status register writedisk_LOOP1: IN AL,DX ;sets AL to status register (which is 8 bits) AND AL, 10000000B JNE writedisk_LOOP1 MOV DX, 1F7h ;status register again writedisk_LOOP2: IN AL, DX ;sets AL to status register again AND AL, 01000000B JE writedisk_LOOP2 ; 设置不使用中断 ;3F6 (Read): Alternate Status Register ;3F6 (Write): Device Control Register mov dx,3F6H mov al,02H out dx,al ; 设置扇区数 8扇区 4KBytes mov dx,1F2H mov al,08H out dx,al ; 设置lba地址数据 ;1F3H (Read and Write): LBA Low Register ;1F4H (Read and Write): LBA Mid Register ;1F5H (Read and Write): LBA High Register mov dx,1F3H mov al,byte [writedisk_clusternum + 0] out dx,al mov dx,1F4H mov al,byte [writedisk_clusternum + 1] out dx,al mov dx,1F5H mov al,byte [writedisk_clusternum + 2] out dx,al ; 设置磁盘和模式 MOV DX, 1F6H ;device/head register MOV AL, 40H ;0 selects device 0 (master). 10h would select device 1 (slave). 40表示lba模式 OUT DX, AL ;selects master device MOV DX, 1F7H ;command register MOV AL, 30H ; OPCODE - 30h (with retries) or 31h (without retries) OUT DX, AL ; sends the command! MOV DX, 1F7H ;status register writedisk_LOOP3: IN AL, DX AND AL, 00001000B ;if DRQ is not high, the device doesn't have data for us JE writedisk_LOOP3 ;yet, so keep looking until it does! MOV DX, 1F0H ;data register MOV esi, dword [writedisk_mempoint] ;points DI to the buffer we're using MOV ecx, 2048 ; 2048 decimal. This controls the REP command. 4K Bytes writeing. CLD ;clear the direction flag so INSW increments DI (not decrements it) REP outsw
ret
testcall:
;push ax
;mov dword [es:di],0x1236
;pop ax retf
|