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

📄 ex8.asm

📁 ART OF Assembly Language Programming, 很不错
💻 ASM
📖 第 1 页 / 共 2 页
字号:
GetWholeNum	proc	near
		lesi	InputLine	;Point es:di at InputLine array.
		gets

		call	Geti		;Get an integer from the line.
		jc	BadInt		;Carry set if error reading integer.
		cmp	ax, 0		;Must have at least one row or column!
		jle	BadInt
		ret

BadInt:		print
		char	Bell
		char	"Illegal integer value, please re-enter",cr,lf,0
		jmp	GetWholeNum
GetWholeNum	endp




; Various routines to call for the cross products we compute.
; On entry, AX contains the first operand, dx contains the second.
; These routines return their result in AX.
; They return AX=8000h if an error occurs.
;
; Note that the CrossProduct function calls these routines indirectly.

addition	proc	far
		add	ax, dx
		jno	AddDone		;Check for signed arithmetic overflow.
		mov	ax, 8000h	;Return 8000h if overflow occurs.
AddDone:	ret
addition	endp


subtraction	proc	far
		sub	ax, dx
		jno	SubDone
		mov	ax, 8000h	;Return 8000h if overflow occurs.
SubDone:	ret
subtraction	endp

multiplication	proc	far
		imul	ax, dx
		jno	MulDone
		mov	ax, 8000h	;Error if overflow occurs.
MulDone:	ret
multiplication	endp

division	proc	far
		push	cx		;Preserve registers we destory.

		mov	cx, dx
		cwd
		test	cx, cx		;See if attempting division by zero.
		je	BadDivide
		idiv	cx

		mov	dx, cx		;Restore the munged register.
		pop	cx
		ret

BadDivide:	mov	ax, 8000h
		mov	dx, cx
		pop	cx
		ret
division	endp


; The following function computes the remainder if the symbol "DoMOD"
; is defined somewhere prior to this point.

		ifdef	DoMOD
modulo		proc	far
		push	cx

		mov	cx, dx
		cwd
		test	cx, cx		;See if attempting division by zero.
		je	BadDivide
		idiv	cx
		mov	ax, dx		;Need to put remainder in AX.
		mov	dx, cx		;Restore the munged registers.
		pop	cx
		ret

BadMod:		mov	ax, 8000h
		mov	dx, cx
		pop	cx
		ret
modulo		endp
		endif



; If you decide to extend the ResultArrays dope vector array, this is a good
; place to define the function for those new arrays.





; The main program that reads the data from the user, calls the appropriate
; routines, and then prints the results.

Main		proc
		mov	ax, dseg
		mov	ds, ax
		mov	es, ax
		meminit


; Prompt the user to enter the number of rows and columns:

GetRows:	print
		byte	"Enter the number of rows for the matrix:",0

		call	GetWholeNum
		mov	Rows, ax

; Okay, read each of the row values from the user:

		print
		char	"Enter values for the row (vertical) array",cr,lf,0

; Malloc allocates the number of bytes specified in the CX register.
; AX contains the number of array elements we want;  multiply this value
; by two since we want an array of words.  On return from malloc, es:di
; points at the array allocated on the "heap".  Save away this pointer in
; the "RowArray" variable.
;
; Note the use of the "wp" symbol. This is an equate to "word ptr" appearing
; in the "matrix.a" include file.  Also note the use of the address expression
; "RowArray+2" to access the segment portion of the double word pointer.

		mov	cx, ax
		shl	cx, 1
		malloc
		mov	wp RowArray, di
		mov	wp RowArray+2, es

; Okay, call "GetArray" to read "ax" input values from the user.
; GetArray expects the number of values to read in AX and a pointer
; to the base address of the array in es:di.

		print
		char	"Enter row data:",0

		mov	ax, Rows	;# of values to read.
		call	GetArray	;ES:DI still points at array.



; Okay, time to repeat this for the column (horizontal) array.

GetCols:	print
		byte	"Enter the number of columns for the matrix:",0

		call	GetWholeNum	;Get # of columns from the user.
		mov	Columns, ax	;Save away number of columns.


; Okay, read each of the column values from the user:

		print
		char	"Enter values for the column (horz.) array",cr,lf,0

; Malloc allocates the number of bytes specified in the CX register.
; AX contains the number of array elements we want;  multiply this value
; by two since we want an array of words.  On return from malloc, es:di
; points at the array allocated on the "heap".  Save away this pointer in
; the "RowArray" variable.

		mov	cx, ax			;Convert # Columns to # bytes
		shl	cx, 1			; by multiply by two.
		malloc				;Get the memory.
		mov	wp ColArray, di		;Save pointer to the
		mov	wp ColArray+2, es	; columns vector (array).

; Okay, call "GetArray" to read "ax" input values from the user.
; GetArray expects the number of values to read in AX and a pointer
; to the base address of the array in es:di.

		print
		char	"Enter Column data:",0

		mov	ax, Columns		;# of values to read.
		call	GetArray		;ES:DI points at column array.


; Okay, initialize the matrices that will hold the cross products.
; Generate RASize copies of the following code.
; The "repeat" macro repeats the statements between the "repeat" and the "endm"
; directives RASize times.  Note the use of the Item symbol to automatically
; generate different indexes for each repetition of the following code.
; The "Item = Item+1" statement ensures that Item will take on the values
; 0, 1, 2, ..., RASize on each repetition of this loop.
;
; Remember, the "repeat..endm" macro copies the statements multiple times
; within the source file, it does not execute a "repeat..until" loop at
; run time.  That is, the following macro is equivalent to making "RASize"
; copies of the code, substituting different values for Item for each
; copy.
;
; The nice thing about this code is that it automatically generates the
; proper amount of initialization code, regardless of the number of items
; placed in the ResultArrays array.


Item		=	0

		repeat	RASize

		mov	cx, Columns		;Compute the size, in bytes,
		imul	cx, Rows		; of the matrix and allocate
		add	cx, cx			; sufficient storage for the
		malloc				; array.

		mov	wp ResultArrays[Item * (sizeof DopeVec)].Data, di
		mov	wp ResultArrays[Item * (sizeof DopeVec)].Data+2, es

		mov	ax, Rows
		mov	ResultArrays[Item * (sizeof DopeVec)].Dim1, ax

		mov	ax, Columns
		mov	ResultArrays[Item * (sizeof DopeVec)].Dim2, ax

		mov	ResultArrays[Item * (sizeof DopeVec)].ESize, 2

Item		=	Item+1
		endm



; Okay, we've got the input values from the user,
; now let's compute the addition, subtraction, multiplication,
; and division tables.  Once again, a macro reduces the amount of
; typing we need to do at this point as well as automatically handling
; however many items are present in the ResultArrays array.

element		=	0

		repeat	RASize
		lfs	bp, RowArray		;Pointer to row data.
		lgs	bx, ColArray		;Pointer to column data.

		lea	cx, ResultArrays[element * (sizeof DopeVec)]
		call	CrossProduct

element		=	element+1
		endm


; Okay, print the arrays down here.  Once again, note the use of the
; repeat..endm macro to save typing and automatically handle additions
; to the ResultArrays array.


Item		=	0

		repeat	RASize
		mov	si, offset ResultArrays[item * (sizeof DopeVec)]
		call	PrintMat
Item		=	Item+1
		endm


; Technically, we don't have to free up the storage malloc'd for each
; of the arrays since the program is about to quit.  However, it's a
; good idea to get used to freeing up all your storage when you're done
; with it.  For example, were you to add code later at the end of this
; program, you would have that extra memory available to that new code.

		les	di, ColArray
		free
		les	di, RowArray
		free

Item		=	0
		repeat	RASize
		les	di, ResultArrays[Item * (sizeof DopeVec)].Data
		free
Item		=	Item+1
		endm


Quit:		ExitPgm			;DOS macro to quit program.
Main		endp

cseg		ends

sseg		segment	para stack 'stack'
stk		byte	1024 dup ("stack   ")
sseg		ends

zzzzzzseg	segment	para public 'zzzzzz'
LastBytes	byte	16 dup (?)
zzzzzzseg	ends
		end	Main

⌨️ 快捷键说明

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