📄 int31h.asm
字号:
mov word ptr ds:[edi+ebx+2],dx ; low word of 32bit linear address
mov byte ptr ds:[edi+ebx+4],cl ; high word of 32bit linear address
mov byte ptr ds:[edi+ebx+7],ch
jmp int31ok ; return ok
;=============================================================================
int310008: ; set segment limit
call int31testsel ; test for valid selector BX
cmp cx,0Fh ; is limit greater than 1M?
jbe @@1 ; if not, jump
or dx,0FFFh ; auto-adjust limit
shrd dx,cx,12 ; DX = low 16 bits of page limit
shr cx,12 ; CL = high 4 bits of page limit
or cl,80h ; set granularity bit in CL
@@1: mov word ptr ds:[edi+ebx],dx ; put low word of limit
and byte ptr ds:[edi+ebx+6],50h ; mask off G and high nibble of limit
or byte ptr ds:[edi+ebx+6],cl ; put high nibble of limit
jmp int31ok ; return ok
;=============================================================================
int310009: ; set descriptor access rights
call int31testsel ; test for valid selector BX
call int31testaccess ; test access bits in CX
or ch,10h ; set AVL bit, descriptor used
and ch,0D0h ; mask off low nibble of CH
and byte ptr ds:[edi+ebx+6],0Fh ; mask off high nibble access rights
or byte ptr ds:[edi+ebx+6],ch ; or in high access rights byte
mov byte ptr ds:[edi+ebx+5],cl ; put low access rights byte
jmp int31ok ; return ok
;=============================================================================
int31000A: ; create alias descriptor
call int31testsel ; test for valid selector BX
xor ax,ax ; allocate descriptor
mov cx,1
int 31h
jc int31fail8011 ; if failed, descriptor unavailable
push ax ; preserve allocated selector
push ds ; copy descriptor and set type data
pop es
movzx edi,ax ; EDI = target selector
mov esi,cs:gdtbase ; ESI -> GDT
add edi,esi ; adjust to target descriptor in GDT
add esi,ebx ; adjust to source descriptor in GDT
movs dword ptr es:[edi],ds:[esi]; copy descriptor
lods dword ptr ds:[esi]
mov ah,92h ; set descriptor type - R/W up data
stos dword ptr es:[edi]
pop ax ; restore allocated selector
jmp int31okax ; return ok, with AX
;=============================================================================
int31000B: ; get descriptor
call int31testsel ; test for valid selector BX
lea esi,[edi+ebx] ; ESI -> descriptor in GDT
mov edi,[esp] ; get EDI buffer ptr from stack
movs dword ptr es:[edi],ds:[esi]; copy descriptor
movs dword ptr es:[edi],ds:[esi]
jmp int31ok ; return ok
;=============================================================================
int31000C: ; set descriptor
call int31testsel ; test for valid selector BX
mov esi,[esp] ; ESI = EDI buffer ptr from stack
mov cx,es:[esi+5] ; get access rights from descriptor
call int31testaccess ; test access bits in CX
push ds ; swap DS and ES, target and source
push es
pop ds
pop es
add edi,ebx ; adjust EDI to descriptor in GDT
movs dword ptr es:[edi],ds:[esi]; copy descriptor
lods dword ptr ds:[esi]
or al,10h ; set descriptor AVL bit
stos word ptr es:[edi]
jmp int31ok ; return ok
;=============================================================================
int31000E: ; get multiple descriptors
mov ax,000Bh ; function 000bh, get descriptor
jmp int31000EF ; go to common function
;=============================================================================
int31000F: ; set multiple descriptors
mov ax,000Ch ; function 000ch, set descriptor
int31000EF: ; common to funcions 000eh and 000fh
test cx,cx ; if CX = 0, return ok immediately
jz int31ok
mov dx,cx ; DX = number of descriptors
xor cx,cx ; CX = successful counter
@@l0: mov bx,es:[edi] ; BX = selector to get
add edi,2
int 31h ; get/set descriptor
jc int31failcx ; if error, fail with AX and CX
add edi,8 ; increment descriptor ptr
inc cx ; increment successful copy counter
dec dx ; decrement loop counter
jnz @@l0 ; if more descriptors to go, loop
jmp int31ok ; return ok
;=============================================================================
; DOS MEMORY FUNCTIONS
;=============================================================================
;=============================================================================
int310100: ; allocate DOS memory block
mov ah,48h ; DOS alloc memory function
call int31010x_f2 ; allocate memory
jc int31failbx ; if fail, exit with AX=err, BX=maxmem
mov dx,ax ; DX=segment of DOS memory block
xor ax,ax ; allocate descriptor
mov cx,1
int 31h
jnc @@1
mov ah,49h ; if error allocating descriptor
call int31010x_f2 ; free what was allocated
jmp int31fail8011 ; and exit with error 8011h
@@1: mov [esp+14h],ax ; set selector in DX
mov [esp+1Ch],dx ; set base address in AX
mov bx,ax
mov cx,dx
shl dx,4
shr cx,12
mov ax,0007h ; set selector base
int 31h
mov cx,0092h ; set access rights
mov al,09h
int 31h
jmp int31010x ; set selector size
;=============================================================================
int310101: ; free DOS block memory
mov ah,49h
mov si,dx ; preserve DX = selector
call int31010x_f1
jc int31failax
mov bx,si ; restore selector in BX
jmp int310001
;=============================================================================
int310102: ; resize DOS block memory
mov ah,4Ah
mov si,dx ; preserve DX = selector
call int31010x_f1
jc int31failbx
mov bx,si ; restore selector in BX
int31010x:
movzx edx,word ptr [esp+10h] ; get original size
shl edx,4 ; convert para to bytes
dec edx ; limit=size-1
shld ecx,edx,16
mov ax,0008h ; set limit
int 31h
jmp int31ok
;-----------------------------------------------------------------------------
int31010x_f1:
pop bp
push ax bx
mov bx,dx ; BX = selector
mov ax,0006h ; get base
int 31h
pop bx ax
jc int31failax
shrd dx,cx,4 ; adjust CX:DX to segment value
push bp
int31010x_f2:
xor cx,cx
push cx ; set real mode SS:SP
push cx
sub esp,10
push dx ; set real mode ES
push cx ; set real mode flags
pushad ; set real mode registers
push ss
pop es
mov edi,esp
mov bl,21h
mov ax,0300h
int 31h
mov bx,[esp+10h] ; get BX from structure
mov ax,[esp+1Ch] ; get AX from structure
lea esp,[esp+32h]
pop bp
jc int31failax ; if error, fail
bt word ptr [esp-14h],0
jmp bp
;=============================================================================
; INTERRUPT FUNCTIONS
;=============================================================================
;=============================================================================
int310200: ; get real mode interrupt vector
movzx ebx,bl ; EBX = BL (interrupt number)
mov dx,[ebx*4+0] ; load real mode vector offset
mov cx,[ebx*4+2] ; load real mode vector segment
jmp int31okdx ; return ok, with AX, CX, DX
;=============================================================================
int310201: ; set real mode interrupt vector
mov ebp,dr7
xor eax,eax ; reset null-ptr protection
mov dr7,eax
movzx ebx,bl ; EBX = BL (interrupt number)
mov [ebx*4+0],dx ; set real mode vector offset
mov [ebx*4+2],cx ; set real mode vector segment
mov dr7,ebp
jmp int31ok ; return ok
;=============================================================================
int310202: ; get protected mode exception handler
mov ds,cs:seldata
cmp bl,20h ; must be in range 00-1Fh
jae int31fail8021 ; invalid value
xor cx,cx
xor edx,edx
cmp bl,10h ; if interrupt not in range 00-0Fh
jae @@done ; return 0000:00000000h
test pm32_mode,00000010b ; if no internal exception handling
jz @@0 ; then read as is
call checkint
jz @@1
@@0: movzx ebx,bl
shl ebx,3 ; adjust for location in IDT
add ebx,idtbase ; add base of IDT
mov ds,selzero
mov edx,dword ptr [ebx+4] ; get high word of offset
mov dx,word ptr [ebx+0] ; get low word of offset
mov cx,word ptr [ebx+2] ; get selector
jmp @@done
@@1: bt excset_pm,bx ; check if EXC is installed
lea edx,exc_matrix[ebx*4] ; load default EIP
mov cx,SELCODE ; load default CS
jnc @@done ; if EXC not installed, then done
mov edx,dptr exctab_pm[ebx*8+0] ; get EIP
mov cx,wptr exctab_pm[ebx*8+4] ; get CS
@@done: mov ax,[esp+28]
jmp int31okedx ; return ok, with AX, CX, EDX
;=============================================================================
int310203: ; set protected mode exception handler
xchg bx,cx ; swap int number with int selector
call int31testsel ; test for valid selector BX
xchg bx,cx
mov ds,cs:seldata
cmp bl,20h ; must be in range 00-1Fh
jae int31fail8021 ; invalid value
cmp bl,10h ; only 16 exceptions are supported
jae @@done
movzx ecx,cx
test pm32_mode,00000010b ; if no internal exception handling
jz @@0 ; then set as is
call checkint
jz @@1
@@0: movzx ebx,bl
shl ebx,3 ; adjust for location in IDT
add ebx,idtbase ; add base of IDT
mov ds,selzero
mov word ptr [ebx+0],dx ; set low word of offset
shr edx,16
mov word ptr [ebx+6],dx ; set high word of offset
mov word ptr [ebx+2],cx ; set selector
jmp @@done
@@1: bts excset_pm,bx ; prepare and set installed bit
mov dptr exctab_pm[ebx*8+0],edx ; set EIP
mov wptr exctab_pm[ebx*8+4],cx ; set CS
cmp cx,SELCODE ; if selector <> kernel selector
jnz @@done ; then we are done
xor eax,eax
btr excset_pm,bx ; reset installed bit
mov dptr exctab_pm[ebx*8+0],eax ; reset EIP
mov wptr exctab_pm[ebx*8+4],ax ; reset CS
@@done: jmp int31ok ; return ok
;=============================================================================
int310204: ; get protected mode interrupt vector
mov ds,cs:seldata
test pm32_mode,00000010b ; if no internal exception handling
jz @@0 ; then read as is
call checkint ; check if one of IRQs
jz @@1 ; if one of IRQs, read from buffer
@@0: movzx ebx,bl
shl ebx,3 ; adjust for location in IDT
add ebx,idtbase ; add base of IDT
mov ds,selzero
mov edx,dword ptr [ebx+4] ; get high word of offset
mov dx,word ptr [ebx+0] ; get low word of offset
mov cx,word ptr [ebx+2] ; get selector
jmp @@done
@@1: bt irqset_pm,si ; check if IRQ is installed
jnc @@2 ; if not, return standard handler
test al,0F0h ; check if IRQ is above INT 00-0Fh
jnz @@0 ; if yes, read as is
mov edx,dptr irqtab_pm[esi*8+0] ; get EIP
mov cx,wptr irqtab_pm[esi*8+4] ; get CS
jmp @@done
@@2: lea edx,std_matrix[esi*4] ; load standard EIP
mov cx,SELCODE ; load standard CS
@@done: mov ax,[esp+28]
jmp int31okedx ; return ok, with AX, CX, EDX
;=============================================================================
int310205: ; set protected mode interrupt vector
xchg bx,cx ; swap int number with int selector
call int31testsel ; test for valid selector BX
xchg bx,cx
mov ds,cs:seldata
mov es,selzero
movzx ecx,cx ; ECX = CX (selector)
test pm32_mode,00000010b ; if no internal exception handling
jz @@0 ; then set as is
call checkint ; check if one of IRQs
jz @@1 ; if one of IRQs, install in buffer
cmp bl,1Bh ; process special interrupts
jz @@1Bh
cmp bl,1Ch
jz @@1Ch
cmp bl,23h
jz @@23h
cmp bl,24h
jz @@24h
@@0: movzx ebx,bl
shl ebx,3 ; adjust for location in IDT
add ebx,idtbase ; add base of IDT
mov word ptr es:[ebx+0],dx ; set low word of offset
shr edx,16
mov word ptr es:[ebx+6],dx ; set high word of offset
mov word ptr es:[ebx+2],cx ; set selector
jmp @@done
@@1: cmp cx,SELCODE ; check if restoring IRQ
jnz @@2 ; if not, jump
btr irqset_rm,si ; reset IRQ installed bit (RM)
btr irqset_pm,si ; reset IRQ installed bit (PM)
mov ebp,irqtab_rm[esi*4] ; restore real mode interrupt
mov es:[ebx*4],ebp
test al,0F0h ; check if IRQ above INT 00-0Fh
jnz @@0 ; if yes, restore prot. mode IRQ
xor eax,eax
mov dptr irqtab_pm[esi*8+0],eax ; reset EIP
mov wptr irqtab_pm[esi*8+4],ax ; reset CS
jmp @@done
@@2: bts irqset_rm,si ; set IRQ installed bit (RM)
bts irqset_pm,si ; set IRQ installed bit (PM)
mov di,_KERNEL
shl edi,16
lea ebp,back_matrix[esi*4] ; get address of real mode IRQ handler
add ebp,edi
mov es:[ebx*4],ebp ; install real mode IRQ callback
mov dptr irqtab_pm[esi*8+0],edx ; install EIP (into IRQ buffer)
mov wptr irqtab_pm[esi*8+4],cx ; install CS (into IRQ buffer)
test al,0F0h ; check if IRQ above INT 00-0Fh
jnz @@0 ; if yes, install as is
@@done: jmp int31ok ; return ok
@@1Bh: cmp cx,SELCODE ; install real mode INT 1Bh callback
mov eax,newint1Bh
jnz @@1Bh0
mov eax,oldint1Bh
@@1Bh0: mov es:[4*1Bh],eax
jmp @@0
@@1Ch: cmp cx,SELCODE ; install real mode INT 1Ch callback
mov eax,newint1Ch
jnz @@1Ch0
mov eax,oldint1Ch
@@1Ch0: mov es:[4*1Ch],eax
jmp @@0
@@23h: cmp cx,SELCODE ; install real mode INT 23h callback
mov eax,newint23h
jnz @@23h0
mov eax,oldint23h
@@23h0: mov es:[4*23h],eax
jmp @@0
@@24h: cmp cx,SELCODE ; install real mode INT 24h callback
mov eax,newint24h
jnz @@24h0
mov eax,oldint24h
@@24h0: mov es:[4*24h],eax
jmp @@0
;=============================================================================
int310900: ; get and disable interrupt state
add esp,26h ; adjust stack
pop ds ; restore DS
btr word ptr [esp+8],9 ; test and clear IF bit in EFLAGS
setc al ; set AL = carry (IF flag from EFLAGS)
jmp int31oknopop ; return ok, dont pop registers
;=============================================================================
int310901: ; get and enable interrupt state
add esp,26h ; adjust stack
pop ds ; restore DS
bts word ptr [esp+8],9 ; test and set IF bit in EFLAGS
setc al ; set AL = carry (IF flag from EFLAGS)
jmp int31oknopop ; return ok, dont pop registers
;=============================================================================
int310902: ; get interrupt state
add esp,26h ; adjust stack
pop ds ; restore DS
bt word ptr [esp+8],9 ; just test IF bit in EFLAGS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -