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

📄 entry.asm

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 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.28 2004/09/12 04:46:27 perditionc 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 callcpm_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, 12hex_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		retdivide_by_zero_message db 0dh,0ah,'Interrupt divide by zero, stack:',0dh,0ah,0                global reloc_call_int0_handlerreloc_call_int0_handler:                                mov si,divide_by_zero_messagezero_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		stithats_it:	hlt		jmp short thats_it  ; it might be command.com that nukesinvalid_opcode_message db 0dh,0ah,'Invalid Opcode at ',0                global reloc_call_int6_handlerreloc_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_1int21_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=userSPint21_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_2int21_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                jbe     int21_normalentryint21_3:                call    dos_crit_sect                mov     cx,_disk_api_tos

⌨️ 快捷键说明

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