📄 sd.asm
字号:
;
; Copyright (C) 1996-2002 Supernar Systems, Ltd. All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are
; met:
;
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
;
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; 3. The end-user documentation included with the redistribution, if any,
; must include the following acknowledgment:
;
; "This product uses DOS/32 Advanced DOS Extender technology."
;
; Alternately, this acknowledgment may appear in the software itself, if
; and wherever such third-party acknowledgments normally appear.
;
; 4. Products derived from this software may not be called "DOS/32A" or
; "DOS/32 Advanced".
;
; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED
; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
;
.486p
.MODEL flat
LOCALS
NOJUMPS
include stddef.inc
.CODE
start32:
push ds es ss fs gs
pushfd
pushad
mov edx,offs __message0
call print_string
call check_d32a_dpmi
call get_d32a_selectors
popad
popfd
pushfd
pushad
call Debug_Init_ ; initialize debugger
call fill_memory_with_ints
mov ebx,__history_bufsize ; setup history buffer
mov ax,0FF91h
int 21h
mov __history_bufbase,ebx
mov __history_bufhand,esi
mov __history_bufnum,0
mov __history_bufptr,0
call check_command_line
test esi,esi
jz @err1
call open_exec
call load_exec_header
call update_environment
mov bx,ds
mov ax,000Ah
int 31h
mov bx,ax
mov dx,wptr __buffer+0
mov cx,wptr __buffer+2
mov ax,0007h
int 31h
push fs
pop gs ; GS = zero selector
mov fs,bx ; FS = buffer selector
mov ax,cs
lar dx,ax
shr dx,8 ; set rights = data
and dx,00060h
xor dx,0C092h
mov _acc_rights,dx
movzx edx,wptr __exec_start+0
movzx ecx,wptr __exec_start+2
mov bx,__exec_handle
mov ax,4200h
int 21h ; move to file start
jc @err4
mov edx,__buffer ; DS:EDX = current ptr
mov ecx,4 ; ECX = bytes to load
mov bx,__exec_handle
mov ax,3F00h
int 21h
jc @err4
movzx edx,wptr __exec_start+0
movzx ecx,wptr __exec_start+2
mov bx,__exec_handle
mov ax,4200h
int 21h ; move to file start
jc @err4
push offs @@2
mov edx,__buffer
mov ax,[edx+0] ; get file signature
mov bx,[edx+2]
test bx,bx
jnz @lerr6
cmp ax,'EL' ; 'LE' type
jz load_le_app
cmp ax,'XL' ; 'LX' type
jz load_lx_app
cmp ax,'CL' ; 'LC' type
jz load_lc_app
jmp @lerr6
@@2: call remove_name_from_cmd
call close_exec
clr ebx
mov ax,0300h
int 10h ; get DOS cursor position
dec dh
dec dh
mov ax,0200h
int 10h
push edx
mov ecx,160
@@l1: mov ax,0E20h
xor ebx,ebx
push ecx
int 10h
pop ecx
loop @@l1
pop edx
mov ax,0200h
int 10h
xor eax,eax
int 33h
cli
cld
mov ax,wptr _sel32_cs
mov wptr _old_cs,ax
mov ax,wptr _sel32_ss
mov wptr _old_ds,ax
mov wptr _old_ss,ax
mov eax,_app_esp
mov dptr _old_esp,eax
mov bx,_sel32_cs ; get application's CS base
mov ax,0006h
int 31h
shl ecx,16
mov cx,dx
add ecx,_app_eip
mov dr0,ecx ; place a breakpoint
mov eax,00000303h
mov dr7,eax
mov __history_bufon,1 ; turn on history buffer
popad
popfd
pop gs fs ss es ds ; restore ES, FS, GS
mov ds,word ptr cs:_sel32_ss ; load new DS
lss esp,fword ptr cs:_app_esp ; load new SS:ESP
jmp fword ptr cs:_app_eip
;=============================================================================
check_d32a_dpmi:
push es ds ; check for DOS/32 Advanced ADPMI
mov esi,offs __idstring
mov ax,0A00h
int 31h
pop ds
mov __api_off,edi
mov __api_sel,es
pop es
jc @err0
mov ax,es
cmp ax,__api_sel
jz @err0
test bl,02h
jz @err2
cmp cl,04h
jb @err6
ret
get_d32a_selectors:
mov al,06h ; get ADPMI selectors
call fword ptr __api_off
mov __kernel_codesel,bx
mov __kernel_datasel,cx
mov __kernel_zerosel,dx
mov __kernel_codeseg,si
mov __client_codesel,di
ret
fill_memory_with_ints:
push es
push ds
pop es
mov ax,0FF90h ; get free memory information
int 21h
mov __free_mem,eax
mov ebx,eax ; allocate memory
mov ax,0FF91h
int 21h
jc @@done
mov __base_mem,ebx
mov eax,0CCCCCCCCh ; set memory to INT 3
mov edi,__base_mem
mov ecx,__free_mem
mov dl,cl
shr ecx,2
rep stosd
mov cl,dl
and cl,3
rep stosb
mov ax,0FF92h ; free memory
int 21h
@@done: pop es
ret
;=============================================================================
@err0: mov edx,offs __error0
call print_string
jmp _abort
@err1: mov edx,offs __error1
call print_string
jmp _abort
@err2: mov edx,offs __error2
call print_string
jmp _abort
@err3: mov edx,offs __error3
call print_string
jmp _abort
@err4: mov edx,offs __error4
call print_string
jmp _abort
@err5: mov edx,offs __error5
call print_string
jmp _abort
@err6: mov edx,offs __error6
call print_string
jmp _abort
;=============================================================================
check_command_line:
mov edi,80h
movzx ecx,byte ptr es:[edi] ; get length of command line
jecxz @@err ; if zero, error
inc edi ; offset to start of command line
mov al,20h
repe scasb ; look for non-space character
jz @@err ; if not found, error
dec edi
inc ecx
mov ebx,edi
@@1: mov al,es:[edi]
cmp al,09h ; look for TAB character
jz @@2
cmp al,0Dh ; look for CR character
jz @@2
cmp al,20h ; look for ' ' character
jz @@2
inc edi
loop @@1
@@2: mov ecx,edi
mov esi,ebx ; SI = pointer to file name
mov edi,ebx ; DI = pointer to file name
sub ecx,ebx
@@done: ret
@@err: xor esi,esi
ret
remove_name_from_cmd:
call check_command_line
jz @@done
mov al,20h
rep stosb
@@done: ret
;-----------------------------------------------------------------------------
update_environment:
push ds es
sub esp,64
mov ebp,esp
mov ah,19h
int 21h
mov dl,al
add al,'A'
mov byte ptr [ebp+0],al ; set drive
mov word ptr [ebp+1],'\:'
inc dl
mov ah,47h
lea esi,[ebp+3]
int 21h ; read directory
push ds
pop es
xor al,al
mov edi,esi
mov ecx,64
repne scasb
cmp byte ptr [edi-2],'\'
jnz @@0
dec edi
@@0: mov byte ptr [edi-1],'\'
mov es,[esp+64]
push edi
call check_command_line
pop edi
push ds
pop es
mov ds,[esp+64]
@@1: lodsb
stosb
test al,al
loopne @@1
xor al,al
stosb
push es
pop ds
mov ecx,-1
mov edi,ebp
repne scasb
not ecx
mov ebx,ecx
mov es,[esp+64]
mov ax,es:[002Ch] ; get environment selector
test ax,ax ; check if selector is NULL
jz @@err ; if yes, jump to error
lar cx,ax
jnz @@err
mov es,ax
xor al,al
xor edi,edi
mov ecx,7FFFh
@@2: repne scasb
scasb
jnz @@2
add edi,2
mov ecx,-1
mov edx,edi
repne scasb
not ecx
cmp ebx,ecx
ja create_new_environment
mov ecx,ebx
mov edi,edx
mov esi,ebp
rep movsb
@@done: add esp,64
pop es ds
ret
@@err: add esp,64
pop es ds
stc
ret
create_new_environment:
push ebx ebp
mov ecx,-1
xor edi,edi
@@1: repne scasb
dec ecx
scasb
jnz @@1
not ecx
add ecx,2
push ecx
add ecx,ebx
shr ecx,4
inc ecx
mov ebx,ecx
mov ax,0100h
int 31h
jc _abort
pop ecx
push es
pop ds
mov es,dx
xor esi,esi
xor edi,edi
rep movsb
pop esi ecx
push ss
pop ds
rep movsb
add esp,64
pop es ds
mov es:[002Ch],dx
ret
;-----------------------------------------------------------------------------
open_exec:
push ds es
push ss es
pop ds es
mov edi,cs:_system_block
rep movsb
mov byte ptr es:[edi],0
push ss
pop ds
mov edx,_system_block
mov ax,3DC0h
int 21h
jc @@1 ; if error opening, try ".EXE"
pop es ds
mov __exec_handle,ax
jc @err3
ret
@@1: mov ebx,_system_block
@@2: cmp byte ptr [ebx],2Eh
stc
jz @@err
inc ebx
cmp ebx,edi
jb @@2
mov eax,4558452Eh
cmp eax,[edi-4]
stc
jz @@err
mov eax,6578652Eh
cmp eax,[edi-4]
stc
jz @@err
mov [edi],eax
mov byte ptr [edi+4],0
mov ax,3DC0h
int 21h
@@err: pop es ds
mov __exec_handle,ax
jc @err3
ret
load_exec_header:
mov ax,3F00h
mov bx,__exec_handle
mov ecx,64 ; ECX = 64 bytes to load
mov edx,__buffer ; DS:EDX = ptr
int 21h
jc @err4
push edx
xor ecx,ecx
xor edx,edx
mov bx,__exec_handle
mov ax,4200h
int 21h ; move to file start
pop edx
jc @err4
xor ebp,ebp ; reset ptr in app
cmp word ptr [edx],'ZM' ; is exec 'MZ' file type
jnz search_for_le ; if not, search for known exec type
mov eax,[edx+18h] ; MZ reloc-tab must be at offset 0040h
cmp ax,40h
jnz search_for_mz
mov eax,[edx+3Ch] ; get start of 32-bit code
test ax,ax ; check if exec is bound
jz search_for_mz ; if not, search
mov __exec_start,eax
mov _app_off_datapages,0
ret
search_for_mz:
xor esi,esi
@@0: movzx eax,wptr [edx+04h] ; get pages in file
shl eax,9 ; *512
movzx ebx,wptr [edx+02h] ; get bytes on last page
add eax,ebx
cmp wptr [edx],'ZM'
jz @@1
cmp wptr [edx],'WB'
jz @@2
jmp @@3
@@1: sub eax,0200h
@@2: mov esi,ebp
add ebp,eax
mov ecx,ebp
mov edx,ebp
shr ecx,16
mov bx,__exec_handle
mov ax,4200h
int 21h ; move to next exec in file
jc @err4
mov ax,3F00h
mov bx,__exec_handle
mov ecx,64
mov edx,__buffer
int 21h
jc @err4
test eax,eax
jz @err5
jmp @@0
@@3: cmp wptr [edx],'EL'
jz @@4
cmp wptr [edx],'XL'
jz @@4
mov ecx,ebp
mov edx,ebp
shr ecx,16
mov bx,__exec_handle
mov ax,4200h
int 21h ; move to next exec in file
jc @err4
call search_for_le
@@4: mov __exec_start,ebp
mov _app_off_datapages,esi
ret
search_for_le:
@@1: mov edx,__buffer ; DS:EDX = current ptr
mov ecx,1000h ; ECX = bytes to load
mov ax,3F00h
mov bx,__exec_handle
int 21h
jc @err4
test eax,eax ; check if no bytes read
jz @err5 ; if true, no app in file
shr ecx,1
@@2: mov ax,[edx+0]
mov bx,[edx+2]
test bx,bx
jnz @@4
cmp ax,'EL' ; 'LE' type
jz @@3
cmp ax,'XL' ; 'LX' type
jz @@3
@@4: cmp ax,'CL' ; 'LC' type (Linear Compressed)
jz @@3
add edx,2
add ebp,2 ; increment pointer in file
loop @@2
jmp @@1
@@3: mov _app_off_datapages,0
ret
close_exec:
mov ah,0Dh ; flush disk buffers
int 21h
mov bx,__exec_handle
mov ah,3Eh
int 21h
ret
print_string:
pushad
clr eax
clr ecx
mov ebx,edx
@@1: cmp al,[ebx]
jz @@2
inc ebx
inc ecx
jmp @@1
@@2: mov eax,4000h
mov ebx,0002h
int 21h
popad
ret
;=============================================================================
Align 4
Debug_:
@debug@ db 0C3h ; RET
xchg eax,[esp]
mov ds:_temp,eax
xchg eax,[esp]
lea esp,[esp+4] ; remove caller from stack, don't change flags
pushfd ; simulate an INT (push eflags)
cli
push cs
push _temp ; push original caller
jmp _int03 ; execute INT 3 handler
;=============================================================================
Align 4
Debug_Init_: ; needed to initialize debugger's INTs
pushfd
pushad
push cs ds es ss fs gs
cli
cld
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -