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

📄 vaxdeciml.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
	.byte	40 , 40 , 40 , 40 , 40 , 40	# illegal decimal digits	.byte	50 , 51 , 52 , 53 , 54		# index  ^x50	.byte	55 , 56 , 57 , 58 , 59		#    to  ^x59	.byte	50 , 50 , 50 , 50 , 50 , 50	# illegal decimal digits	.byte	60 , 61 , 62 , 63 , 64		# index  ^x60	.byte	65 , 66 , 67 , 68 , 69		#    to  ^x69	.byte	60 , 60 , 60 , 60 , 60 , 60	# illegal decimal digits	.byte	70 , 71 , 72 , 73 , 74		# index  ^x70	.byte	75 , 76 , 77 , 78 , 79		#    to  ^x79	.byte	70 , 70 , 70 , 70 , 70 , 70	# illegal decimal digits	.byte	80 , 81 , 82 , 83 , 84 		# index  ^x80	.byte	85 , 86 , 87 , 88 , 89		#    to  ^x89	.byte	80 , 80 , 80 , 80 , 80 , 80	# illegal decimal digits	.byte	90 , 91 , 92 , 93 , 94 		# index  ^x90	.byte	95 , 96 , 97 , 98 , 99		#    to  ^x99	.byte	90 , 90 , 90 , 90 , 90 , 90	# illegal decimal digits #+ #		binary number to decimal equivalent # # the following table is used to do a fast conversion from a binary number # stored in a byte to its decimal representation. the table structure assumes # that the number lies in the range 0 to 99. numbers that lie outside this # range produce unpredictable resutls. #- #		decimal equivalents			     binary #		-------------------			     ------binary_to_packed_table:	.byte	0x00 , 0x01 , 0x02 , 0x03 , 0x04 	#  0 through  9	.byte	0x05 , 0x06 , 0x07 , 0x08 , 0x09 	# 	.byte	0x10 , 0x11 , 0x12 , 0x13 , 0x14	# 10 through 19	.byte	0x15 , 0x16 , 0x17 , 0x18 , 0x19 	# 	.byte	0x20 , 0x21 , 0x22 , 0x23 , 0x24	# 20 through 29	.byte	0x25 , 0x26 , 0x27 , 0x28 , 0x29 	# 	.byte	0x30 , 0x31 , 0x32 , 0x33 , 0x34	# 30 through 39	.byte	0x35 , 0x36 , 0x37 , 0x38 , 0x39 	# 	.byte	0x40 , 0x41 , 0x42 , 0x43 , 0x44 	# 40 through 49	.byte	0x45 , 0x46 , 0x47 , 0x48 , 0x49 	# 	.byte	0x50 , 0x51 , 0x52 , 0x53 , 0x54	# 50 through 59	.byte	0x55 , 0x56 , 0x57 , 0x58 , 0x59 	# 	.byte	0x60 , 0x61 , 0x62 , 0x63 , 0x64 	# 60 through 69	.byte	0x65 , 0x66 , 0x67 , 0x68 , 0x69 	# 	.byte	0x70 , 0x71 , 0x72 , 0x73 , 0x74	# 70 through 79	.byte	0x75 , 0x76 , 0x77 , 0x78 , 0x79 	# 	.byte	0x80 , 0x81 , 0x82 , 0x83 , 0x84	# 80 through 89	.byte	0x85 , 0x86 , 0x87 , 0x88 , 0x89 	# 	.byte	0x90 , 0x91 , 0x92 , 0x93 , 0x94	# 90 through 99	.byte	0x95 , 0x96 , 0x97 , 0x98 , 0x99 	#  #+ # functional description: # #	in 4 operand format, the addend string specified by  the  addend  length #	and  addend address operands is added to the sum string specified by the #	sum length and sum address operands and the sum string  is  replaced  by #	the result. # # input parameters: # #	r0 - addlen.rw		number of digits in addend string #	r1 - addaddr.ab		address of addend decimal string #	r2 - sumlen.rw		number of digits in sum string #	r3 - sumaddr.ab		address of sum decimal string # # output parameters: # #	r0 = 0 #	r1 = address of the byte containing the most significant digit of #	     the addend string #	r2 = 0 #	r3 = address of the byte containing the most significant digit of #	     the string containing the sum # # condition codes: # #	n <- sum string lss 0 #	z <- sum string eql 0 #	v <- decimal overflow #	c <- 0 # # register usage: # #	this routine uses all of the general registers. the condition codes  #	are recorded in r11 as the routine executes. #-vax$addp4:	pushr	$0xfff		# save registers 0,1,2,3,4,5,6,7,8,9,10,11	clrl	r9		# this is addition2:	movq	r2,r4		# let r4 and r5 describe output string #+ # all four routines converge at this point and execute common initialization # code until a later decision is made to do addition or subtraction. # #	r4 - number of digits in destination string #	r5 - address of destination string # #	r9 - indicates whether operation is addition or subtraction #		0 => addition #		1 => subtraction #-3:	movpsl	r11			# get initial psl	insv	$psl$m_z,$0,$4,r11	# set z-bit, clear the rest	movab	decimal_pack,r10	# store address of handler/* 	No need to check operand size because the routines that call us *      all have defined operand sizes. * *	roprand_check	r2		# insure that r2 is lequ 31 */	bsbw	strip_zeros_r2_r3	# strip high order zeros from r2/r3 string/*	roprand_check	r0		# insure that r0 is lequ 31 */	bsbw	strip_zeros_r0_r1	# strip high order zeros from r0/r1 string # rather than totally confuse the already complicated logic dealing with # different length strings in the add or subtract loop, we will put the # result into an intermediate buffer on the stack. this buffer will be long # enough to handle the worst case so that the addition loop need only concern # itself with the lengths of the two input loops. the required length is 17 # bytes, to handle an addition with a carry out of the most significant byte. # we will allocate 20 bytes to maintain whatever alignment the stack has.	clrq	-(sp)			# set aside space for output string	clrq	-(sp)			# worst case string needs 16 bytes	clrl	-(sp)			# add slack for a carry	extzv	$1,$4,r4,r8		# get byte count of destination string	addl3	r8,r5,-(sp)		# save high address end of destination	movab	24(sp),r5		# point r5 one byte beyond buffer # the number of minus signs will determine whether the real operation that we # perform is addition or subtraction. that is, two plus signs or two minus # signs will both result in addition, while a plus sign and a minus sign will # result in subtraction. the addition and subtraction routines have their own # methods for determining the correct sign of the result.  #  # for the purpose of counting minus signs, we treat subtraction as the # addition of the negative of the input operand. that is, subtraction of a # positive quantity causes the sign to be remembered as minus and counted as # a minus sign while subtraction of a minus quantity stores a plus sign and # counts nothing.  #  # on input to this code sequence, r9 distinguished addition from subtraction. # on output, it contains either 0, 1, or 2, indicating the total number of # minus signs, real or implied, that we counted. 	extzv	$1,$4,r0,r6		# get byte count for first input string	addl2	r6,r1			# point r1 to byte containing sign	bicb3	$0xf0,(r1),r6		# r6 contains the sign "digit"/* *	No need to check this because we only need addition * *	jlbs	r9,35$			# use second case if subtraction */ # this case statement is used for addition 	caseb	r6,$10,$15-10L1:					# dispatch on sign digit	.word	5f-L1			# 10 => sign is "+"	.word	4f-L1			# 11 => sign is "-"	.word	5f-L1			# 12 => sign is "+"	.word	4f-L1			# 13 => sign is "-"	.word	5f-L1			# 14 => sign is "+"	.word	5f-L1			# 15 => sign is "+"4:	movl	$1,r9			# count a minus sign	movzbl	$13,r6			# the preferred minus sign is 13	jbr	L60			# now check second input sign5:	clrl	r9			# no real minus signs so far	movzbl	$12,r6			# the preferred minus sign is 12L60:	extzv	$1,$4,r2,r7		# get byte count for second input string	addl2	r7,r3			# point r3 to byte containing sign	bicb3	$0xf0,(r3),r7	# r7 contains the sign "digit"	caseb	r7,$10,$15-10L2:					# dispatch	.word	8f-L2			# 10 => sign is "+"	.word	7f-L2			# 11 => sign is "-"	.word	8f-L2			# 12 => sign is "+"	.word	7f-L2			# 13 => sign is "-"	.word	8f-L2			# 14 => sign is "+"	.word	8f-L2			# 15 => sign is "+"7:	incl	r9			# remember that sign was minus	movzbl	$13,r7			# the preferred minus sign is 13	jbr	L90			# now check second input sign8:	movzbl	$12,r7			# the preferred minus sign is 12L90:	jlbc	r9,add_packed		# even parity indicates addition/* *	Don't need this because we don't do subtraction * *	jbr	subtract_packed		# odd parity calls for subtraction */ #+ # functional description: # #	this routine adds two packed decimal strings whose descriptors #	are passed as input parameters and places their sum into another #	(perhaps identical) packed decimal string. # #	at the present time, the result is placed into a 16-byte storage #	area while the sum is being evaluated. this drastically reduces #	the number of different cases that must be dealt with as each #	pair of bytes in the two input strings is added. # #	the signs of the two input strings have already been dealt with #	so this routine performs addition in all cases, even if the original #	entry was at subp4 or subp6. the cases that arrive in this routine #	are as follows. # #                          r2/r3           r0/r1          result #                    +---------------+---------------+---------------+ #                    |               |               |               | #      r2/r3 + r0/r1 |     plus      |     plus      |     plus      | #                    |               |               |               | #                    +---------------+---------------+---------------+ #                    |               |               |               | #      r2/r3 + r0/r1 |     minus     |     minus     |     minus     | #                    |               |               |               | #                    +---------------+---------------+---------------+ #                    |               |               |               | #      r2/r3 - r0/r1 |     minus     |     plus      |     minus     | #                    |               |               |               | #                    +---------------+---------------+---------------+ #                    |               |               |               | #      r2/r3 - r0/r1 |     plus      |     minus     |     plus      | #                    |               |               |               | #                    +---------------+---------------+---------------+ # #	note that the correct choice of sign in all four cases is the sign #	of the second input string, the one described by r2 and r3. # # input parameters: # #	r0<4:0> - number of digits in first input decimal string #	r1      - address of least significant digit of first input  #		  decimal string (the byte containing the sign) # #	r2<4:0> - number of digits in second input decimal string #	r3      - address of least significant digit of second input  #		  decimal string (the byte containing the sign) # #	r4<4:0> - number of digits in output decimal string #	r5      - address of one byte beyond least significant digit of  #		  intermediate string stored on the stack # #	r6<3:0> - sign of first input string in preferred form #	r7<3:0> - sign of second input string in preferred form # #	r11     - saved psl (z-bit is set, other condition codes are clear) # #	(sp)	- saved r5, address of least significant digit of ultimate #		  destination string. #	4(sp)   - beginning of 20-byte buffer to hold intermediate result # # output parameters: # #	the particular input operation (addpx or subpx) is completed in #	this routine. see the routine headers for the four routines that #	request addition or subtraction for a list of output parameters #	from this routine. #-add_packed:	movb	r7,r9			# use sign of second string for output	jlbc	r9,1f			# check if sign is negative	bisb2	$psl$m_n,r11		# ... so the saved n-bit can be set1:	bicb3	$0x0f,(r1),r6		# get least significant digit to r6	bicb3	$0x0f,(r3),r7		# get least significant digit to r7	clrl	r8			# start the add with carry off	bsbw	add_packed_byte_r6_r7	# add the two low order digits # the following set of instructions computes the number of bytes in the two # strings and, if necessary, performs a switch so that r0 and r1 always # describe the shorter of the two strings.	extzv	$1,$4,r0,r0		# convert digit count to byte count	extzv	$1,$4,r2,r2		# do it for both strings	cmpl	r0,r2			# we want to compare the byte counts	blequ	2f			# skip the swap if we're already correct	movq	r0,r6			# save the longer	movq	r2,r0			# store the shorter on r0 and r1	movq	r6,r2			# ... and store the longer in r2 and r32:	subl2	r0,r2			# make r2 a difference (r2 gequ 0) # r0 now contains the number of bytes remaining in the shorter string. # r2 contains the difference in bytes between the two input strings.	tstl	r0			# does shorter string have any room?	beql	4f			# skip loop if no room at all3:	bsbw	add_packed_byte_string	# add the next two bytes together	sobgtr	r0,3b			# check for end of loop4:	tstl	r2			# does longer string have any room?	beql	7f			# skip next loops if all done5:	jlbc	r8,6f			# life is simple if carry clear/*  note that r6 is a loop invariant here and can be removed from the loop if *  we carefully document this assumption in the per-byte addition routine. the

⌨️ 快捷键说明

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