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

📄 vaxexception.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 3 页
字号:
	movl	r4,r2			#copy address of current frame	bsbw	oldsp			#calculate value of sp before call	movl	chf$l_mcharglst+4(r2),r2 #get address of mechanism argument list	tstl	chf$l_mch_depth(r2)	#check if this is a vectored handler	blss	8f			#if so, don't skip any frames7:	cmpl	r4,chf$l_mch_frame(r2)	#unwound to establisher frame?	beql	L10			#if eql yes	moval	loopunwind,savpc(r4)	#set frame unwind address	movl	savfp(r4),r4		#get address of previous frame	brb	7b			#8:	tstl	r3			#any more frames to consider?	bleq	9f			#if leq no	moval	loopunwind,r0		#set frame unwind address	bsbb	setpc			#	brb	6b			#  # # modify change of flow return if new address specified # 9:	movl	newpc(ap),r0		#get change of flow return address	beql	L15			#if eql none specified	bsbb	setpc			#set new final return addressL15:	movzwl	$ss$_normal,r0		#set normal completion	ret				#0:	movzwl	$ss$_insframe,r0	#set insufficient frames	ret				#  # # subroutine to store unwind pc. it checks if the frame being altered # is an ast call frame. rather than plug its return pc, we let # it return to the ast dispatcher, who will dismiss the ast. instead, # we plug the interrupt pc of the ast, so the rei goes back to # loopunwind to continue with the ast dismissed. #setpc:/*	cmpl	savpc(r4),$exe$astret	#check if frame is an ast *	beql	1f			#branch if yes */	movl	r0,savpc(r4)		#set frame unwind address	rsb/* *1:	movl	r4,r2 *	bsbw	oldsp			#find the start of the ast arg list *	moval	loopunwind,16(r2)	#and stuff the ast pc *	bicl2	$psl$m_cm|psl$m_fpd,20(r2) #clean out cm and fpd bits *	rsb */ # # unwind handler frame # startunwind:				#start of actual unwind	movl	chf$l_mcharglst+4(sp),r0 #get address of mechanism argument list	movq	chf$l_mch_savr0(r0),r0	#restore registers r0 and r1  # # unwind call frame signaling condition handler if one is specified # loopunwind:				#unwind call frame	tstl	(fp)			#condition handler specified?	beql	L20			#if eql no	movzwl	$ss$_unwind,-(sp)	#push unwind signal condition	pushl	$1			#push number of signal arguments #	pushr	$^m<r0,r1>		#push registers r0 and r1	 pushr	$0x03	pushl	$0			#push frame depth	pushl	fp			#push frame address	pushl	$4			#push number of mechanism arguments	pushal	(sp)			#push address of mechanism arguments	pushal	24(sp)			#push address of signal argumentscallunwind:				#signal unwind	calls	$2,*(fp)		#call condition handler	movq	chf$l_mch_savr0(sp),r0	#retrieve new values for r0 and r1L20:	moval	savrg(fp),ap		#get address of register save area	blbc	savmsk(fp),2f		#if lbc r0 not saved	movl	r0,(ap)+		#save r0 for subsequent restoration2:	bbc	$1,savmsk(fp),4f	#if clr, r1 not saved	movl	r1,(ap)			#save r1 for subsequent restoration/* *3:	cmpl	savpc(fp),$exe$astret	#about to unwind an ast? *	bneq	4f			#branch if not *	pushr	$0x06			#save r1 and r2 *	movl	fp,r2 *	bsbb	oldsp			#find the ast parameter list *#	popl	r1			#get back r1 *	 movl	r1,(sp)+ *	movq	r0,8(r2)		#stuff r0 and r1 so they will pass through *#	popl	r2			#restore r2 *	 movl	r2,(sp)+ */4:	ret				# # # subroutine to calculate value of sp before call # oldsp:	extzv	$14,$2,savmsk(r2),-(sp)	#get stack alignment bias	extzv	$0,$12,savmsk(r2),r1	#get register save mask	addl2	$savrg,r2		#add offset to register save area	addl2	(sp)+,r2		#add stack alignment bias1:	blbc	r1,2f			#if lbc corresponding register not saved	addl2	$4,r2			#adjust for saved register2:	ashl	$-1,r1,r1		#any more registers saved?	bneq	1b			#if neq yes	rsb				# #/* * *	This routine is used call any of the conditional handler during *	the process of unwinding */	.globl	sys$call_handlsys$call_handl:	callg	4(sp),(r1)	rsb #define acmode 4				# access mode to adjust stack pointer for#define adjust 8				# 16-bit signed adjustment value#define newadr 12				# address of longword to store updated value #+ # sys$adjstk - adjust outer mode stack pointer # # this service provides the capability to adjust the stack pointer for # a mode that is less privileged than the calling access mode. it can be # used to load an initial value into the specified mode's stack pointer or # to adjust its current value. # # inputs: # #		acmode(ap) = access mode to adjust stack pointer for. #		adjust(ap) = 16-bit signed adjustment value. #		newadr(ap) = address of longword to store updated value. #			if the initial contents of @newadr(ap) are nonzero, #			then the value is taken as the current top of stack. #			else the current stack pointer for the specified mode #			is used. # # outputs: # #	r0 low bit clear indicates failure to adjust stack pointer. # #		r0 = ss$_accvio - longword to store updated stack pointer #			or part of new stack segment cannot be written by #			calling access mode. # #		r0 = ss$_nopriv - specifed access mode is equal or more #			privileged than calling access mode. # #	r0 low bit set indicates successful completion. # #		r0 = ss$_normal - normal completion. #-  #	.entry	exe$adjstk,^m<r2,r3,r4,r5,r6>sys$adjstk:	.word	0x07c	movl	newadr(ap),r5		#get address to store new stack value	extzv	$0,$2,acmode(ap),r3	#get access mode to modify stack pointer for	movpsl	r2			#read current psl	cmpzv	$psl$v_prvmod,$psl$s_prvmod,r2,r3 #previous mode more privileged?	bgeq	6f			#if geq no #	ifnowrt	#4,(r5),40$		#can new stack value be written?	 probew	$0,$4,(r5)		#001 can new stack value be written?	 beql	4f			#001 br if it can't	movl	(r5),r6			#get specified stack value	bneq	1f			#if neq value specified	mfpr	r3,r6			#1:	cvtwl	adjust(ap),r0		#get adjustment value	addl2	r0,r6			#calculate new top of stack	mnegl	r0,r0			#allocation of stack space?	bleq	3f			#if leq no	movl	r6,r1			#copy new stack value	cvtwl	$-0x200,r2		#set addition constant2: #	ifnowrt	r0,(r1),40$,r3		#can allocated stack segment be written?	 probew	r3,r0,(r1)		#001 can new stack value be written	 beql	4f			#001 br if it can't	subl2	r2,r1			#update address in stack	movaw	(r0)[r2],r0		#update remaining length	bgeq	2b			#if geq more to check3:	mtpr	r6,r3			#	movl	r6,(r5)			#store new stack value	movzwl	$ss$_normal,r0		#set normal completion	ret				#4:	cmpl	$psl$c_user,r3		#is this for user mode stack?	bneq	5f			#br if not #	pushr	#^m<r1,r2,r3,r4,r5>	#save registers	 pushr	$0x03e #	movl	r1,r2			#stack base address	pushl	r1			#001 push address to grow	calls	$1,_grow		#001 try to grow #	bsbw	exe$expandstk		#augment stack to make accessible #	popr	#^m<r1,r2,r3,r4,r5>	#restore registers	 popr	$0x03e 	blbs	r0,1f			#repeat checks 	ret				#return error code 5:	movzwl	$ss$_accvio,r0		#set access violation	ret				#6:	movzwl	$ss$_nopriv,r0		#set no privilege	ret				# #/* * *	This routine is called when there are no handlers set. This should *	always be true since Ultrix does not use the conditional *	handler mechanism.  The only case this is not true is in the *	float point emulation code where it does set a conditional handler. *	 */default_handler:	.word	0	pushab	handle_exception	# push the default handler	pushl	$0			# set number of frames to unwind	calls	$2,exe$unwind		# call the system unwind routine	movl	$ss$_normal,r0		# indicate normal	ret #/* *	This routine will interface the VMS exception handling that is *	used by the emulation package to the Ultrix signal facility * * Input: *	(sp) - return address of sys$call_handl *    04(sp) - number of condtion arg *    08(sp) - addr of signal arg list *    12(sp) - addr of mechanism arf list *    16(sp) - number of mechanism arg. *    20(sp) - fp of handler establisher frame *    24(sp) - frame depth *    28(sp) - saved r0 *    32(sp) - saved r1 *    36(sp) - flags longword *    40(sp) - number of signal args *    44(sp) - exception name *    48(sp) - first exception parameter (if any ) *    52(sp) - second exception parameter (if any) *	 . *	 . *	 . *	(sp) - exception pc *	(sp) - exception psl */ handle_exception:/* *	Get everthing off the stack up to the number of signal args */	tstl	(sp)+			# pop return address	movq	24(sp),r0		# restore r0 and r1	movab	36(sp),sp		# adjust to the signal number/* *		(sp) - number of signal args *   	     N*4(sp) - exception name *       	 .   - exception specific information *	 	 . *  	   N*4+4(sp) - exception pc *	   N*4+8(sp) - exception psl */		movpsl	-(sp)					# get the current psl	extzv	$psl$v_curmod,$psl$s_curmod,(sp),(sp)+	# are we in kernel mode	beql	kern_handling				# br if yes/* *	We are in user mode but to do any of the ultrix signaling *	we need to get into kernel mode so that we can use the Utlrix *	signal facility. * * 	The halt instruction is used to change our *	mode to kernel so that we can use the signal code. This works *	because in the privilege instruction code, in locore.s, will *	check the PC of the exception. If the exception address *	equals vax$special_halt it will jump to vax$special_cont, *	otherwise it will proceed normally. */	.globl	vax$special_haltvax$special_halt:        halt	/* *	This routine is called if the pervious mode and the current mode *	of the psl are not the same. The routine purpose is to copy *	the exception information from the previous mode stack to the *	kernel stack. */	.globl	vax$special_contvax$special_cont:	/* *	At most we need type 5 location for the exception information and *	one location for the address that points to the stuff that was copied *      to the kernel stack */	movab	-6*4(sp),sp			# at most  new entries						# are going on the stack	pushr	$0x0f				# save r0 r1 r2 r3/* *	Stack looks as follows * *	0(sp)	saved r3 *	4(sp)	saved r2 *	8(sp)	saved r1 *     12(sp)	saved r0 *     16(sp)	address of the copied exception information *     20(sp) *	 . *	 .	exception information area *	 . *     36(sp) */	movpsl	r2				# get the psl	extzv	$psl$v_prvmod,$psl$s_prvmod,r2,r2 # get the previous mode	mfpr	r2,r0				# get user stack pointer	movab	20(sp),r3			# r3 = address of scratch						# area	movl	(r0),r1				# get number of user stack						# entries we have	subl3	r1,$5,-(sp)			# subtract from the max no.	ashl	$2,(sp),(sp)			# longword aligned	addl2	(sp)+,r3			# r3 = start address of 						# exception area	movl	r3,16(sp)			# set the address/* *	The previous stack look as follows: * *	0(r0)	signal number *	4(r0)	exception name *	 .	 *	 .	exception specific information *	 (r0)	pc *	 (r0)	psl */	tstl	(r0)+				# skip by num of signal args1:	movl	(r0)+,(r3)+			# move user stack to kernel 						# stack	sobgtr	r1,1b				# cont until done	mtpr	r0,r2				# reset user stack	popr	$0x0f				# restore r0 r1 r2 r3	movl	(sp),sp				# set the address of the						# exception information	brb	start_handling			# handle the exception/* *	If we were already in kernal there is no need to copy the *	stack, but we do need to pop the signal arg count off. */kern_handling:	tstl	(sp)+				# pop of the signal count/* *	Start handling the excpetion * *		(sp) - exception name *		 . *	 	 .	exception parameters * 	 	 . *         N*4+4(sp) - exception pc * 	   N*4+*(sp) - exception psl */start_handling:/* *	Check for access violation */	cmpl	$ss$_accvio,(sp)	# Is this a access violation?	bneq	1f			# br if no	tstl	(sp)+			# pop of exception name	jmp	_Xprotflt1		# jump handler/* *	Check for reserved address */1:	cmpl	$ss$_radrmod,(sp)	# Is this a reserved address	bneq	2f			# br if no	tstl	(sp)+			# pop of exception name	jmp	_Xresadflt		# jump to handler/* *	Check for reserved operand */2:	cmpl	$ss$_roprand,(sp)	# Is this reserved operand	bneq	3f			# br if no	tstl	(sp)+			# pop of exception name	jmp	_Xresopflt		# jump to handler/* *	Reserved opcode */ 3:	cmpl	$vax$_opcdec,(sp)	bneq	4f	tstl	(sp)+	jmp	_Xprivinflt/* *	Reserved opcode with fpd */ 4:	cmpl	$vax$_opcdec_fpd,(sp)	bneq	5f	tstl	(sp)+	jmp	_Xprivinflt/* *	Check for the all the arithmetic traps and faults */5:	cmpl	(sp),$ss$_intovf		# Is it in ..	blss	6f				# between the ..	cmpl	(sp),$ss$_fltund_f		# arithtrap ..	bgtr	6f				# trap, if true then/* *	We must subtract ss$_artress and divide by 8 to get the  *	hardware values of the trap and fault numbers. The reason *	for this is the variable constants were defined as *	(ss$_artress + 8 * <hardware constants value > ).  This is *	done to be consistent with the way VMS does it in the emulation *	code. */	subl2	$ss$_artres,(sp)			divl2	$8,(sp)	jmp	_Xarithtrap			# jmp to the Ultrix						# routine that handles these						# traps/* *	Something is wrong */6:	movpsl	r0			# *slr001* get psl	extzv	$psl$v_curmod,$psl$s_curmod,r0,r0						# *slr001* get current mode	beql	1f			# br if zero ( kernel )	halt				# indicate that something is wrong1:	pushab	pnstr2			# slr001 get address of string to print	calls	$1,_panic		# *slr001* call panic routinepnstr2:	.ascii	"vaxexception: fatal emulation error handling error type\n"

⌨️ 快捷键说明

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