;N!_1--G6_11
;PROGRAM TITLE GOES HERE-- n!
;**********************************************************
data_seg        segment		;define data segment
  n_v		dw	5
  result	dw	?
data_seg        ends
;**********************************************************
stack_seg	segment
	dw	128 dup(0)
  tos	label	word
stack_seg	ends
;***********************************************************
code1   segment			;define code segment
;----------------------------------------------------------
main	proc	far		;main part of program

	assume cs:code1,ds:data_seg,ss:stack_seg

start:				;starting execution address

	mov	ax,stack_seg	;set up stack and SP
	mov	ss,ax
	mov	sp,offset tos
;
	push	ds		;save old data segment
	sub	ax,ax		;put zero in AX	
	push	ax		;save it on stack
;
	mov	ax,data_seg	;data segment addr
	mov	ds,ax	  	;  into DS register
  
;MAIN PART OF PROGRAM GOES HERE
	mov	bx,offset result;push addr of result
	push	bx		
	mov	bx,n_v		;push n
	push	bx
	call	far ptr fact
	ret			;return to DOS

main	endp			;end of main part of program
;-----------------------------------------------------------
code1	ends
;***********************************************************
code	segment
;
  frame	struc
	save_bp		dw	?
 	save_cs_ip	dw	2 dup(?)
	n		dw	?
	result_addr	dw	?
  frame	ends
;
	assume	cs:code
;----------------------------------------------------------
fact	proc	far		;define subprocedure

	push	bp		;save BP
	mov	bp,sp		;BP points to frame
	push	bx		;save registers used
	push	ax
	mov	bx,[bp].result_addr;load addr of result
				;     in to BX
	mov	ax,[bp].n	;load n
	cmp	ax,0		;n=0?
	je	done
	push	bx		;push addr of result 
				;  for next call
	dec	ax		;push n-1 
	push	ax		;  for next call
	call	far ptr fact
	mov	bx,[bp].result_addr
	mov	ax,[bx]		;(AX)= n * result
	mul	[bp].n
	jmp	short return
done:	mov	ax,1		;(AX)=1
return:	mov	[bx],ax		;result=(AX)
	pop	ax		;restore registers used
	pop	bx
	pop	bp
	ret	4		;return


fact    endp			;end subprocedure
;----------------------------------------------------------
code    ends			;end of code segment
;**********************************************************

	end	start		;end assembly
