· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Функции BIOS в защищенном режиме

Посл.отвђт Сообщенiе


Дата: Май 29, 2004 16:23:36

Как вызывать Функции BIOS в защищенном режиме?
Насколько я понимаю надо перейти в виртуальный режим.
Хотелось бы посмотреть на примеры перехода в виртуальный режим и на вызов функций BIOS!
Заранее благодарен!


Дата: Май 29, 2004 16:40:39

DPMI


Дата: Май 30, 2004 10:21:53

Читай статьи Ицзелиона на сайте. (уроки VxD)


Дата: Май 30, 2004 12:05:30

Что-то вроде тестового примера (dpmi):
.386
NewProgramSize equ 5000h        ; New Program Size = ~20 KBytes
NewStackOfs    equ NewProgramSize - 0002h
PSPSize        equ 100h
NewCodeSize    equ 1000h        ; New code size exept PSP
V86StackSize   equ 200h
NewPrgStruc    struc            ; New program MAP
PSP            db PSPSize dup(?); Old and new PSP
OurCode        db (NewCodeSize-PSPSize) dup(?)
V86Stack       db V86StackSize dup(?) ; For call v86 interrupt
DPMIArea       db ?             ; Segment for DPMI jump structure
NewPrgStruc    ends             ; New program MAP - end
CallDPMIStruc struc
RegEDI  dd ?
RegESI  dd ?
RegEBP  dd ?
Rezer   dd ?
RegEBX  dd ?
RegEDX  dd ?
RegECX  dd ?
RegEAX  dd ?
flags   dw ?
RegES   dw ?
RegDS   dw ?
RegFS   dw ?
RegGS   dw ?
RegIP   dw ?
RegCS   dw ?
RegSP   dw ?
RegSS   dw ?
CallDPMIStruc ends
text segment byte public use16
	assume cs:text,ds:text
	org 100h
begin:
        mov  ah,48h
        mov  bx,0100h
        int  21h                ; Try to allocate 1000h bytes

        mov  sp,NewStackOfs     ; Set new stack
        mov  bx,NewProgramSize shr 4
        mov  ah,4ah
        int  21h                ; Set new program size
        jnc  @MemFree
        call @Error
        jmp  @GoDos
@MemFree:
;--------------------------------------------------------------------- --------
;INT 2F - DOS Protected-Mode Interface - INSTALLATION CHECK
;	AX = 1687h
;Return: AX = 0000h if installed
;	    BX = flags
;		bit 0: 32-bit programs supported
;	    CL = processor type (02h=80286, 03h=80386, 04h=80486)
;	    DH = DPMI major version
;	    DL = two-digit DPMI minor version (binary)
;	    SI = number of paragraphs of DOS extender private data
;	    ES:DI -> DPMI mode-switch entry point (see #2001)
;	AX nonzero if not installed
;SeeAlso: AX=1686h,AX=43E0h,AX=DE01h/BX=4450h,AX=FB42h/BX=0001h
;SeeAlso: INT 31/AX=0400h,INT 31/AX=5702h,INT D4/AH=10h
;
;(Table 2001)
;Call DPMI mode switch entry point with:
;	AX = flags
;	    bit 0: set if 32-bit program
;	ES = real mode segment of buffer for DPMI private data (ignored if
;		SI was zero)
;Return: CF set on error
;	    program still in real mode
;	    AX = error code (DPMI 1.0+)
;	       8011h unable to allocate all necessary descriptors
;	       8021h 32-bit program specified, but 16-bit DPMI host
;	CF clear if successful
;	    CS = 16-bit selector corresponding to real-mode CS
;	    SS = selector corresponding to real-mode SS (64K limit)
;	    DS = selector corresponding to real-mode DS (64K limit)
;	    ES = selector to program's PSP (100h byte limit)
;	    FS = GS = 0
;	    high word of ESP = 0 if 32-bit program
;	    program now in protected mode
;Note:	this entry point is only called for the initial switch to protected
;	  mode

; Call VMM (vxd-service)
;INT 2F - MS Windows - GET DEVICE API ENTRY POINT
;	AX = 1684h
;	BX = virtual device (VxD) ID (see #1968)
;	ES:DI = 0000h:0000h
;Return: ES:DI -> VxD API entry point, or 0:0 if the VxD does not support an API

	pusha
	push es
	mov  ax,1684h
;;	mov  bx,0001h ; VMM32.vxd
;;	mov  bx,0006h ; V86MMGR
	mov  bx,0021h ; (virtual device ID for PAGEFILE device) (see #1968)
	xor  di,di
	mov  es,di
        int  2fh
; Check getting entry point
	mov  ax,es
	test ax,di
	jz   @@VMMNotValid
; Ok entry point
        mov  word ptr ds:VMMEntry,di
        mov  word ptr ds:VMMEntry+2,es
; Try to get version
	mov  ax,0
	call dword ptr ds:VMMEntry
@@VMMNotValid:
	pop  es
	popa

        mov  ax,1687h
        int  2fh
        test ax,ax
        jz   @DPMIOK
        mov  dx,offset NoDPMI
        call Message
        jmp  @GoDos
@DPMIOk:
        call DPMI_Info
        call Swith_Protected
@GoDos: mov  ax,4c00h
        int  21h
DPMI_Info proc near
        mov  word ptr ds:DPMIEntry,di
        mov  word ptr ds:DPMIEntry+2,es
        mov  ax,es
        push ds
        pop  es
        push di
        mov  di,offset EntPo + 17
        call HexChar
        pop  ax
        mov  di,offset EntPo + 22
        call HexChar
        mov  ax,dx
        mov  di,offset DPMIVer + 39
        call HexChar
        mov  dx,offset DPMIVer
        call Message
        xor  ch,ch
        sub  cl,2
        shl  cl,1
        mov  di,cx
        mov  dx,ProcOfs[di]
        call Message
        mov  dx,offset Bit32
        test bl,1
        jnz  @32Ok
        mov  byte ptr Bit32+28,'N'
@32Ok:  call Message
        mov  dx,offset EntPo
        call Message
        retn
DPMI_Info endp
Swith_Protected proc near
; Swith to Protected Mode
        call DPMICall_Ini
        mov  ax,cs
        add  ax,(DPMIArea shr 4) ; Segment for DPMI jump structure
        mov  es,ax
        mov  ax,0000h
        mov  bx,0000h
        call dword ptr DPMIEntry
        jnc  @InPro
        mov  dx,offset SwError
        call Message
        retn
@InPro: mov  dx,offset InProt
        call Message
;@Stop:  in   al,60h
;        cmp  al,57
;        jnz  @Stop

;INT 31 P - DPMI 0.9+ - SET SEGMENT LIMIT
;	AX = 0008h
;	BX = selector
;	CX:DX = segment limit
;Return: CF clear if successful
;	CF set on error
;	    AX = error code (DPMI 1.0+) (8021h,8022h,8025h) (see #2398)
;Notes:	CX must be zero for 16-bit DPMI implementations
;	limits greater than 1MB must be page aligned (low 12 bits set)
;	only modify descriptors allocated with INT 31/AX=0000h
;	DPMI 1.0+ automatically reloads any segment registers containing the
;	  selector being modified
;	not supported by MS Windows 3.0 in Standard mode

        mov  ax,0008h
        mov  bx,es
        xor  cx,cx
        mov  dx,1000h
        int  31h             ; Set new limit
        jnc  @NewLimit
        mov  dx,offset LimError
        call Message
        jmp  @ToRealMode
@NewLimit:
        mov  al,es:[101h]    ; Exeption ! If not new limit set...

;INT 31 P - DPMI 0.9+ - SIMULATE REAL MODE INTERRUPT
;	AX = 0300h
;	BL = interrupt number
;	BH = flags
;	    bit 0: reset the interrupt controller and A20 line (DPMI 0.9)
;		    reserved, must be 0 (DPMI 1.0+)
;	    others: reserved, must be 0
;	CX = number of words to copy from protected mode to real mode stack
;	ES:(E)DI = selector:offset of real mode call structure (see #2403)
;Return: CF clear if successful
;	    real mode call structure modified (all fields except SS:SP, CS:IP
;	      filled with return values from real mode interrupt)
;	CF set on error
;	    AX = error code (DPMI 1.0+) (8012h,8013h,8014h,8021h)(see #2398)
;	protected mode stack unchanged
        mov  bl,16h  ; Call int 16h
        mov  byte ptr CallDPMIS.RegEAX+1,0 ; reg ah=0h
        lahf
        and  ah,0feh
        mov  bh,ah
        mov  cx,0
        mov  di,offset CallDPMIS
        and  edi,0ffffh
        push ds
        pop  es
        mov  ax,0300h
        int  31h
        jnc  @CallV86
        mov  dx,offset CallV86Error
        call Message
        jmp  @ToRealMode
@CallV86:
; Goto real mode
@ToRealMode:
        mov  ax,4c00h
        int  21h             ; Goto real mode ?!
        retn
Swith_Protected endp
DPMICall_Ini proc near
        mov  bx,offset CallDPMIS
        mov  [bx].RegEDI,edi
        mov  [bx].RegESI,esi
        mov  [bx].RegEBP,ebp
        mov  [bx].Rezer,0
        mov  [bx].RegEBX,ebx
        mov  [bx].RegEDX,edx
        mov  [bx].RegECX,ecx
        mov  [bx].RegEAX,eax
        lahf
        shr  ax,8
        mov  [bx].flags,ax
        mov  [bx].RegES,es
        mov  [bx].RegDS,ds
        mov  [bx].RegFS,fs
        mov  [bx].RegGS,gs
        call $+3
        pop  ax
        mov  [bx].RegIP,ax
        mov  [bx].RegCS,cs
        mov  [bx].RegSP,NewPrgStruc.V86Stack+V86StackSize-2
        mov  [bx].RegSS,ss
        retn
DPMICall_Ini endp
@Error: mov  dx,offset ErrorMess
        call Message
        retn
Message proc near
        mov  ah,09h
	int  21h
	retn
Message endp
PutKeys proc near
        cld
@Key:   lodsw
        test ax,ax
        jnz  @NoEndKey
        retn
@NoEndKey:
        mov  cx,ax
        call PutKey
        jmp  short @Key
PutKeys endp
PutKey proc near
        mov  ah,05h
        int  16h
        retn
PutKey endp
HexChar proc near
        pusha
        mov  cx,4
        mov  bx,offset TabHex
@GetHex:rol  ax,4
        push ax
        and  al,0fh
        xlat
        stosb
        pop  ax
        loop @GetHex
        popa
        retn
TabHex  db '0123456789abcdef'
HexChar endp
DecChar proc near
        pusha
        mov  cx,5
        mov  bx,10000
@GetDec:
        xor  dx,dx
        div  bx
        add  al,'0'
        stosb
        push dx
        xor  dx,dx
        mov  ax,bx
        mov  bx,10
        div  bx
        mov  bx,ax
        pop  ax
        loop @GetDec
        popa
        retn
DecChar endp
ErrorMess    db 'Error !',13,10,'$'
NoDPMI       db 'DPMI isn"t present !!!',13,10,'$'
DPMIVer      db 'major version of DPMI spec supported = 0000',13,10,'$'
ProcOfs      dw offset Proc286,offset Proc386,offset Proc486
Proc286      db 'Current processor is 80286',13,10,'$'
Proc386      db 'Current processor is 80386',13,10,'$'
Proc486      db 'Current processor is 80486',13,10,'$'
Bit32        db 'Supported 32-bits programs: Y',13,10,'$'
EntPo        db 'DPMI entry point 0000:0000',13,10,'$'
SwError      db 'Error at switched to PM !!!',13,10,'$'
InProt       db 'We are in Protected Mode ! Press any key...',13,10,'$'
LimError     db 'Error at change selector limit !!!',13,10,'$'
CallV86Error db 'Error at call V86 Interrupt !!!',13,10,'$'
DPMIEntry    dd ?
VMMEntry     dd ?
CallDPMIS CallDPMIStruc <>
;Offset	Size	Description	(Table 2403)
text ends
	end begin


Дата: Май 30, 2004 16:51:04

> Как вызывать Функции BIOS в защищенном режиме?
в общем случае - никак. нужно создать свой V86 и отмапить туда код BIOS'а
в DOS и производных от нее системах есть экстендеры, реализующие DPMI-интерфейс (Dos Prot-mode Interface), который частично поддерживает win 3.x, win 9x и практически совсем не поддерживает NT.
проще всего вызывать DPMI-Функции из 16-режима, делается это примерно так:
mov  ax, 0300h        ; DPMI симуляция real-mode прерывания
mov  bl, bIntVec      ; вектор прерывания
mov  bh, 01h       
xor  cx, cx           ; кол-во слов, копироуемых со стека PM в стек RM == 0
les  di, lpCallStruct ; указатель на call-struct. (смотри брауна)
int  31h              ; DMPI-сервис
jc   _error_


помещаем это в 16-разряную DLL, копилируем любым 16-разрядным компилятором/ассемблером (и то, и другое входит в состав DDK) и радуемся жизни.

в DOS все тоже самое, только без DLL'ей.

в ядре немного сложнее и для кооректного вызова BIOS надо создавать поток в контексте 16-разрядного процесса win32 подсистемы и оттуда уже юзать DMPI.

в качестве упражнения по программированию можно раздербанить подсистему csrss и посмотреть как она устроена, а потом самому создать свой v86. лично я свой V86 написал только с третьей попытке, а первые две не смог отладить ;-(


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.058