📄 sloader.asm
字号:
call check_range
mov gs:[edi+4],dx
ret
check_range:
test word ptr [ebp+ebx+12],1000h ; check if 16:16 alias requird
jnz @@1 ; if yes, jump
test cl,10h
jnz @@1
@@0: mov ecx,_app_tmp_addr2
mov dx,[ebp+ecx+14] ; get selector
ret
@@1: test cl,10h
jz @@0
mov ecx,_app_tmp_addr2
mov dx,[ebp+ecx+14] ; get selector
test eax,0FFFF0000h ; check 64K range
jnz @lerr5
ret
even
fix_tab label dword
dd fix_byte ; 00h
dd fix_invalid ; 01h
dd fix_16sel ; 02h
dd fix_1616ptr ; 03h
dd fix_invalid ; 04h
dd fix_16off ; 05h
dd fix_1632ptr ; 06h
dd fix_32off ; 07h
dd fix_32selfrel ; 08h
fix_invalid:
jmp @lerr4
;-----------------------------------------------------------------------------
; In: EAX = size
; Out: EDI = address
;
fill_zero_pages:
push es eax ecx edx edi
push gs
pop es
mov dl,cl
shr ecx,2
clr eax
rep stosd
mov cl,dl
and cl,3
rep stosb
pop edi edx ecx eax es
ret
;-----------------------------------------------------------------------------
; In: EAX = size
; Out: EDI = address
;
alloc_block:
push dx
test eax,eax
jz @@done
mov dl,00110000b ; get misc byte
shr dx,4 ; get memory alloc bits in bit1,0
and dx,3 ; mask them
jz @@00 ; if 00b alloc scheme, jump
dec dx
jz @@01
dec dx
jz @@10
dec dx
jz @@11
@@done: pop dx
ret
;
; load 16bit/32bit -> low, then high, then error
;
@@00: call alloc_dos_mem ; try to allocate DOS memory block
jnc @@done ; if allocated, jump
call alloc_dpmi_mem ; try to allocate DPMI memory block
jnc @@done ; if allocated, jump
jmp @lerr3 ; if failed, error
;
; load 16bit -> low, then high, then error
; load 32bit -> high only, then error
;
@@01: test cx,2000h ; check if 32bit Object
jnz @@01_1 ; if yes, jump
call alloc_dos_mem
jnc @@done ; if allocated, jump
@@01_1: call alloc_dpmi_mem
jnc @@done ; if allocated, jump
jmp @lerr3 ; if failed, error
;
; load 16bit/32bit low, then error
;
@@10: call alloc_dos_mem
jnc @@done
jmp @lerr3 ; if failed, error
;
; load 16bit/32bit high, then error
;
@@11: call alloc_dpmi_mem
jnc @@done
jmp @lerr3 ; if failed, error
;-----------------------------------------------------------------------------
alloc_dos_mem:
push eax ebp ; EAX = size to allocate
add eax,0Fh ; align size on para
shr eax,4
test eax,0FFFF0000h ; check high word of EAX
stc
jnz @@done
sub esp,32h
mov ebp,esp
mov byte ptr [ebp+1Dh],48h ; DOS func: AH=48h
mov word ptr [ebp+10h],ax ; DOS BX=size
call int21h
movzx edi,word ptr [ebp+1Ch] ; get returned value in EAX
shl edi,4 ; NOTE: addres is relative to 0
btr word ptr [ebp+20h],0 ; check for errors
lea esp,[esp+32h]
@@done: pop ebp eax
ret
;-----------------------------------------------------------------------------
alloc_dpmi_mem:
push esi ebx ecx edx eax
mov cx,ax ; convert EAX bytes to BX:CX
mov ebx,eax
shr ebx,16
mov ax,0501h ; allocate DPMI memory
int 31h
jc @@done
xor edx,edx
test cx,0FFFh ; check if returned addr aligned
jz @@1 ; on PAGE boundary, if yes, jump
shl ebx,16 ; convert BX:CX addr to EAX
mov bx,cx
mov eax,ebx
add ebx,0FFFh
and bx,0F000h ; align linear addr on PAGE boundary
sub ebx,eax ; calculate difference
mov edx,ebx
add ebx,[esp]
mov cx,bx
shr ebx,16
mov ax,0503h ; resize DPMI memory block
int 31h
jc @@done
@@1: shl ebx,16 ; get new addr (should be the same)
mov bx,cx
lea edi,[ebx+edx] ; adjust linear address
test di,0FFFh
stc
jnz @@done
clc
@@done: pop eax edx ecx ebx esi
ret
;-----------------------------------------------------------------------------
create_selector:
push ebx ecx edx esi edi
mov ax,dx
mov ecx,ebp ; ECX = Virtual Size[Object]
mov dx,_acc_rights ; default: PAGE, USE32, DATA
test ax,0004h ; check if object is executable
jz @@1 ; if not, jump
or dx,0008h ; set selector to Code
@@1: test ax,2000h ; check if object is 32bit
jz @@2 ; if not, jump
xor edi,edi ; set base to Zero
or ecx,-1 ; set limit to 4Gb
jmp @@3
@@2: and dx,0BFFFh ; set selector to 16bit
@@3: call set_descriptor ; allocate selector
jc @lerr2
pop edi esi
mov [esp+2],ax ; store selector in high word of EDX
mov edx,_obj_sel_ptr
mov _obj_selector[edx*2],ax
mov _obj_address[edx*4],edi
inc _obj_sel_ptr
pop edx ecx ebx
cmp ecx,_app_eip_object ; is Current_Object# == EIP_Object#
jnz @@l1 ; if not, jump
mov _sel32_cs,ax
mov _unreloc_eip,edi
test dx,2000h
jz @@l1
add _app_eip,edi
@@l1: cmp ecx,_app_esp_object ; is Current_Object# == ESP_Object#
jnz @@l2 ; if not, jump
mov _sel32_ss,ax
add _app_esp,edi ; adjust ESP
mov _unreloc_esp,edi
@@l2: ret
preload_fixups:
mov ebx,_app_siz_fixrecstab ; allocate memory for fixups
mov ax,0FF91h
int 21h
jc @lerr3 ; if not enough memory, error
mov _app_buf_fixrecstab,esi
mov edx,_app_off_fixpagetab ; move file ptr to fixups
call seek_from_start
mov edx,ebx
mov ecx,_app_siz_fixrecstab
call load_gs_block
mov eax,_app_off_fixrectab
mov ebx,_app_off_fixpagetab
sub eax,ebx
add eax,edx
mov _app_off_fixpagetab,edx
mov _app_off_fixrectab,eax
@@done: ret
unload_fixups:
push es
mov ecx,_app_siz_fixrecstab
mov edi,_app_off_fixpagetab
mov eax,0CCCCCCCCh
mov dl,cl
shr ecx,2
push ds
pop es
rep stosd
mov cl,dl
and cl,3
rep stosb
mov esi,_app_buf_fixrecstab
mov ax,0FF92h
int 21h
pop es
ret
;=============================================================================
int21h: push ebx ; simulate INT 21h (DOS API)
mov bx,21h
push ecx edi es
xor ecx,ecx
xor eax,eax
mov [ebp+20h],ax ; clear Flags
mov [ebp+2Eh],eax ; clear SS:SP
push ss
pop es
mov edi,ebp
mov ax,0300h
int 31h
pop es edi ecx
pop ebx
ret
set_descriptor: ; EDI=base, ECX=limit, DX=access
push ebx ecx edx ebp
mov ebp,ecx
xor ax,ax ; allocate descriptor
mov cx,1
int 31h
jc @@err
mov bx,ax
mov ax,0009h ; set access rights
mov cx,dx
int 31h
jc @@err
mov ax,0007h ; set base
mov ecx,edi
mov dx,cx
shr ecx,16
int 31h
jc @@err
mov ax,0008h ; set limit
mov ecx,ebp
mov dx,cx
shr ecx,16
int 31h
jc @@err
mov ax,bx
clc
@@err: pop ebp edx ecx ebx
ret
seek_from_start:
push ebx ecx edx eax
mov ecx,edx
shr ecx,16
mov bx,__exec_handle
mov ax,4200h
int 21h
pop eax edx ecx ebx
jc @err4
ret
load_fs_block:
push ebx ds
mov bx,__exec_handle
push fs
pop ds
mov ah,3Fh
int 21h
pop ds ebx
jc @err4
ret
load_gs_block:
push ebx
mov bx,__exec_handle
mov ah,3Fh
int 21h
pop ebx
jc @err4
ret
@lerr1: mov edx,offs __lerror1
call print_string
jmp _abort
@lerr2: mov edx,offs __lerror2
call print_string
jmp _abort
@lerr3: mov edx,offs __lerror3
call print_string
jmp _abort
@lerr4: mov edx,offs __lerror4
call print_string
jmp _abort
@lerr5: mov edx,offs __lerror5
call print_string
jmp _abort
@lerr6: mov edx,offs __lerror6
call print_string
jmp _abort
@lerr7: mov edx,offs __lerror7
call print_string
jmp _abort
@lerr8: mov edx,offs __lerror8
call print_string
jmp _abort
.DATA
;屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -