⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entry.asm

📁 开源DOS的C代码源程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;
; File:
;                          entry.asm
; Description:
;                      System call entry code
;
;                       Copyright (c) 1998
;                       Pasquale J. Villani
;                       All Rights Reserved
;
; This file is part of DOS-C.
;
; DOS-C is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version
; 2, or (at your option) any later version.
;
; DOS-C is distributed in the hope that it will be useful, but
; WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
; the GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public
; License along with DOS-C; see the file COPYING.  If not,
; write to the Free Software Foundation, 675 Mass Ave,
; Cambridge, MA 02139, USA.
;
; $Id: entry.asm,v 1.27 2004/05/30 19:31:07 bartoldeman Exp $
;

		%include "segs.inc"
                %include "stacks.inc"

segment	HMA_TEXT
                extern   _int21_syscall
                extern   _int21_service
                extern   _int2526_handler
                extern   _error_tos:wrt DGROUP
                extern   _char_api_tos:wrt DGROUP
                extern   _disk_api_tos:wrt DGROUP
                extern   _user_r:wrt DGROUP
                extern   _ErrorMode:wrt DGROUP
                extern   _InDOS:wrt DGROUP
                extern   _cu_psp:wrt DGROUP
                extern   _MachineId:wrt DGROUP
                extern   critical_sp:wrt DGROUP

                extern   int21regs_seg:wrt DGROUP
                extern   int21regs_off:wrt DGROUP

                extern   _Int21AX:wrt DGROUP

		extern	_DGROUP_

                global  reloc_call_cpm_entry
                global  reloc_call_int20_handler
                global  reloc_call_int21_handler
                global  reloc_call_low_int25_handler
                global  reloc_call_low_int26_handler
                global  reloc_call_int27_handler

;
; MS-DOS CP/M style entry point
;
;       VOID FAR
;       cpm_entry(iregs UserRegs)
;
; This one is a strange one.  The call is to psp:0005h but it returns to the
; function after the call.  What we do is convert it to a normal call and
; fudge the stack to look like an int 21h call.
;
reloc_call_cpm_entry:
                ; Stack is:
                ;       return offset
                ;       psp seg
                ;       000ah
                ;
                push    bp              ; trash old return address
                mov     bp,sp
                xchg    bp,[2+bp]
                pop     bp
                pushf                   ; start setting up int 21h stack
                ;
                ; now stack is
                ;       return offset
                ;       psp seg
                ;       flags
                ;
                push    bp
                mov     bp,sp           ; set up reference frame
                ;
                ; reference frame stack is
                ;       return offset           bp + 6
                ;       psp seg                 bp + 4
                ;       flags                   bp + 2
                ;       bp              <---    bp
                ;
                push    ax
                mov     ax,[2+bp]        ; get the flags
                xchg    ax,[6+bp]        ; swap with return address
                mov     [2+bp],ax
                pop     ax              ; restore working registers
                pop     bp
                ;
                ; Done. Stack is
                ;       flags
                ;       psp seg (alias .COM cs)
                ;       return offset
                ;
                cmp     cl,024h
                jbe     cpm_error
                mov     ah,cl           ; get the call # from cl to ah
                jmp     reloc_call_int21_handler    ; do the system call
cpm_error:      mov     al,0
                iret

;
; interrupt zero divide handler:
; print a message 'Interrupt divide by zero'
; Terminate the current process
;
;       VOID INRPT far
;       int20_handler(iregs UserRegs)
;

print_hex:	mov	cl, 12
hex_loop:
		mov	ax, dx                             
		shr	ax, cl
		and	al, 0fh
		cmp	al, 10
		sbb	al, 69h
		das
                mov 	bx, 0070h
                mov	ah, 0eh
                int	10h
		sub 	cl, 4
		jae 	hex_loop
		ret

divide_by_zero_message db 0dh,0ah,'Interrupt divide by zero, stack:',0dh,0ah,0

                global reloc_call_int0_handler
reloc_call_int0_handler:
                
                mov si,divide_by_zero_message

zero_message_loop:
                mov al, [cs:si]
                test al,al
                je   zero_done

                inc si
                mov bx, 0070h
                mov ah, 0eh
                
                int  10h
                
                jmp short zero_message_loop
                
zero_done:
		mov bp, sp		
		xor si, si	   ; print 13 words of stack for debugging LUDIV etc.
stack_loop:		
                mov dx, [bp+si]
		call print_hex
		mov al, ' '
		int 10h
		inc si
		inc si
		cmp si, 13*2
		jb stack_loop
		mov al, 0dh
		int 10h
		mov al, 0ah
		int 10h
												
                mov ax,04c7fh       ; terminate with errorlevel 127                                                
                int 21h
		sti
thats_it:	hlt
		jmp short thats_it  ; it might be command.com that nukes

invalid_opcode_message db 0dh,0ah,'Invalid Opcode at ',0

                global reloc_call_int6_handler
reloc_call_int6_handler:

                mov si,invalid_opcode_message
                jmp short zero_message_loop        

;
; Terminate the current process
;
;       VOID INRPT far
;       int20_handler(iregs UserRegs)
;
reloc_call_int20_handler:
                mov     ah,0            ; terminate through int 21h


;
; MS-DOS system call entry point
;
;       VOID INRPT far
;       int21_handler(iregs UserRegs)
;
reloc_call_int21_handler:
                ;
                ; Create the stack frame for C call.  This is done to
                ; preserve machine state and provide a C structure for
                ; access to registers.
                ;
                ; Since this is an interrupt routine, CS, IP and flags were
                ; pushed onto the stack by the processor, completing the
                ; stack frame.
                ;
                ; NB: stack frame is MS-DOS dependent and not compatible
                ; with compiler interrupt stack frames.
                ;
                sti
                PUSH$ALL
                mov bp,sp
                Protect386Registers
                ;
                ; Create kernel reference frame.
                ;
                ; NB: At this point, SS != DS and won't be set that way
                ; until later when which stack to run on is determined.
                ;
int21_reentry:
                mov     dx,[cs:_DGROUP_]
                mov     ds,dx

                cmp     ah,25h
                je      int21_user
                cmp     ah,33h
                je      int21_user
                cmp     ah,35h
                je      int21_user
                cmp     ah,50h
                je      int21_user
                cmp     ah,51h
                je      int21_user
                cmp     ah,62h
                jne     int21_1

int21_user:     
                call    dos_crit_sect

                push    ss
                push    bp
                call    _int21_syscall
                pop     cx
                pop     cx
                jmp     short int21_ret

;
; normal entry, use one of our 4 stacks
; 
; DX=DGROUP
; CX=STACK
; SI=userSS
; BX=userSP


int21_1:
                mov si,ss   ; save user stack, to be retored later


                ;
                ; Now DS is set, let's save our stack for rentry (???TE)
                ;
                ; I don't know who needs that, but ... (TE)
                ;
                mov     word [_user_r+2],ss
                mov     word [_user_r],bp  			  ; store and init

                ;
                ; Decide which stack to run on.
                ;
                ; Unlike previous versions of DOS-C, we need to do this here
                ; to guarantee the user stack for critical error handling.
                ; We need to do the int 24h from this stack location.
                ;
                ; There are actually four stacks to run on. The first is the
                ; user stack which is determined by system call number in
                ; AH.  The next is the error stack determined by _ErrorMode.
                ; Then there's the character stack also determined by system
                ; call number.  Finally, all others run on the disk stack.
                ; They are evaluated in that order.

                cmp     byte [_ErrorMode],0
                je      int21_2

int21_onerrorstack:                
                mov     cx,_error_tos


                cli
                mov     ss,dx
                mov     sp,cx
                sti
                
                push    si  ; user SS:SP
                push    bp
                
                call    _int21_service
                jmp     short int21_exit_nodec

                
int21_2:        inc     byte [_InDOS]
                mov     cx,_char_api_tos
                or      ah,ah   
                jz      int21_3
                cmp     ah,0ch
                jle     int21_normalentry

int21_3:
                call    dos_crit_sect
                mov     cx,_disk_api_tos

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -