实验四 子程序设计

实验四 子程序设计

一、实验目的

1. 掌握主程序与子程序间参数传递的方法。

2. 掌握将复杂的应用问题分解为简单小问题的方法,深刻理解“自定向下,逐步求精”的思想。

二、实验内容

1…编写一个求n!的子程序,利用它求1!+2! +3! +4! +5! +6! +7! +8! 的和并输出。要求参数传递分别采用 寄存器传递、全局变量传递,堆栈传递三种不同的方法实现。

寄存器传递
include vcIO.inc
include io32.inc
.data  
	sum dword 0
.code
main proc
	mov ebx,1
	.while ebx<=8
		call fac   ;阶乘子程序
		add sum,eax
		inc ebx
	.endw
	mov eax,sum
	call dispuid
	call dispcrlf
	ret
main endp
fac proc
	mov ecx,1
	mov eax,1
	.while ecx<=ebx
		imul eax,ecx
		inc ecx
	.endw
	ret
fac endp
end main
全局变量传递
include vcIO.inc
include io32.inc
.data  
	sum dword 0
	temp dword ?
.code
main proc
	mov temp,1
	.while temp<=8
		call fac   ;阶乘子程序
		add sum,eax
		inc temp
	.endw
	mov eax,sum
	call dispuid
	call dispcrlf
	ret
main endp
fac proc
	mov ecx,1
	mov eax,1
	.while ecx<=temp   ;temp入口参数(共享变量)
		imul eax,ecx   ;eax出口参数(寄存器)
		inc ecx
	.endw
	ret
fac endp
end main
堆栈传递
include vcIO.inc
include io32.inc
.data  
	sum dword 0
	temp dword ?
.code
main proc
	mov temp,1
	.while temp<=8
		push temp
		call fac   ;阶乘子程序
		add sum,eax
		inc temp
	.endw
	mov eax,sum
	call dispuid
	call dispcrlf
	ret
main endp
fac proc
	push ebp
	mov ebp,esp
	mov ecx,1
	mov eax,1
	.while ecx<=[ebp+8]   ;入口参数(堆栈)
		imul eax,ecx   ;eax出口参数(寄存器)
		inc ecx
	.endw
	pop ebp
	ret 1*4
fac endp
end main

2. 编写一个判断闰年的子程序,利用它求出2010年到2060年之间所有的闰年并输出。 建议采用堆栈传递参数,显示输出格式:每行5个。

全局变量:
include vcIO.inc
include io32.inc
.data  
	year dword ?
	flag dword 0
.code
main proc
mov year,2010
	.while(year<=2060)
		call leap
		cmp flag,1
		jne next
		mov eax,year
		call dispuid
		call dispcrlf
	next: 
		inc year
	.endw
	ret
main endp
leap proc
	mov flag,0
	mov eax,year
	xor edx,edx
	mov ebx,400
	div ebx
	cmp edx,0
	jz tab1
	mov eax,year
	xor edx,edx
	mov ebx,4
	div ebx
	cmp edx,0
	jnz tab2
	mov eax,year
	xor edx,edx
	mov ebx,100
	div ebx
	cmp edx,0
	jz tab2
tab1:
	mov flag,1
tab2:
	ret
leap endp
end main
堆栈传递参数:
include vcIO.inc
include io32.inc
.data  
	flag dword 0
.code
main proc
	mov ecx,2010
	.while(ecx<=2060)
		push ecx
		call leap
		cmp flag,1
		jne next
		mov eax,ecx
		call dispuid
		call dispcrlf
	next: 
		inc ecx
	.endw
	ret
main endp
leap proc
	push ebp
	mov ebp,esp
	mov flag,0
	mov eax,[ebp+8]
	xor edx,edx
	mov ebx,400
	div ebx
	cmp edx,0
	jz tab1
	mov eax,[ebp+8]
	xor edx,edx
	mov ebx,4
	div ebx
	cmp edx,0
	jnz tab2
	mov eax,[ebp+8]
	xor edx,edx
	mov ebx,100
	div ebx
	cmp edx,0
	jz tab2
tab1:
	mov flag,1
tab2:
	pop ebp
	ret 1*4
leap endp
end main

3.编写一个子程序(Prime),用于测试一个整数是否是素数,主、子程序间参数传递通过堆栈完成。利用Prime子程序求出2~100之间的所有素数,并将它们存入Parray数组中,素数的个数存入变量Pcounter中,显示输出所有素数及素数个数。

include vcIO.inc
include io32.inc
.data  
	Prime dword 100 dup(?)
	pcounter dword ?
	flag byte ?
.code
main proc
	xor esi,esi
	mov ecx,2
	.while(ecx<=100)
		push offset flag
		push ecx
		call prime
		cmp flag,1
		jne next
		mov Prime[esi*4],ecx
		inc esi
		mov eax,ecx
		call dispuid
		call dispcrlf
		next: 
			inc ecx
	.endw
	mov pcounter,esi ;素数个数
	ret
main endp
prime proc
	push ebp
	mov ebp,esp
	push eax
	push ecx
	mov ebx,[ebp+12]
	mov byte ptr [ebx],1
	mov eax,[ebp+8]
	mov edi,eax
	mov ecx,eax
	shr ecx,1
	.while(ecx>=2)
		mov eax,edi
		xor edx,edx
		div ecx
		or edx,edx
		jnz next
		mov byte ptr [ebx],0
		jmp restore
	next:
		dec ecx
	.endw
	restore:
		pop ecx
		pop eax
		pop ebp
		ret 2*4
prime endp
end main

4. 编写一个子程序(Gcd),求两个数最大公约数,主、子程序间参数传递通过堆栈完成。调用Gcd子程序求三个双字变量:dvar1、dvar2与dvar3的最大公约数并输出。

include vcIO.inc
include io32.inc
.data  
	dvar1 dword 36
	dvar2 dword 24
	dvar3 dword 16
	dgcd dword ?
	fmtStr byte 'gcd(%d,%d,%d)=%d',13,10,0
.code
main proc
	push dvar1
	push dvar2
	call gcd
	push dvar3
	push dgcd
	call gcd
	invoke printf,offset fmtStr,dvar1,dvar2,dvar3,dgcd
	ret
main endp
gcd proc
	push ebp
	mov ebp,esp
	mov eax,[ebp+12]
	mov ecx,[ebp+8]
	xor edx,edx
	div ecx
	.while(edx!=0)
		mov eax,ecx
		mov ecx,edx
		xor edx,edx
		div ecx
	.endw
	mov dgcd,ecx
	pop ebp
	ret 2*4
gcd endp
end main
思考题:调用一个子程序输出两个双字变量dvar1、dvar2的最小公倍数

5. 编写一个子程序,将一个32位二进制数用8位十六进制形式显示在屏幕上。采用堆栈方法传递参数。

提示:子程序功能是以字符形式显示一个8位十六进制数。

include vcIO.inc
include io32.inc
.data
	wvar dword 307281AFH
.code
	start:
		push wvar
		call disp
		add esp,4
		mov al,'H'
		call dispcrlf
		call dispc
	disp proc
		push ebp
		mov ebp,esp
		push ebx
		push ecx
		mov ecx,8
		mov eax,[ebp+8]
	dhw1:
		rol eax,4
		mov ebx,eax
		and al,0fh
		add al,30h
		cmp al,'9'
		jbe dhw2
		add al,7
	dhw2:
		call dispc
		mov eax,ebx
		loop dhw1
		pop ecx
		pop ebx
		pop ebp
		ret
	disp endp
	exit 0
	end start

6.编写一个子程序(Bubble)完成冒泡排序,主、子程序间参数传递通过堆栈完成;主程序调用子程序完成排序,在主程序中显示排序后的结果。

include vcIO.inc
include io32.inc
.data  
	array dword 12,4,199,122,-33,0
	count equ lengthof array
.code
main proc
	push offset array
	push count
	call bubble
	xor esi,esi
	.while(esi<count)
		mov eax,array[esi*4]
		call dispsid
		call dispcrlf
		inc esi
	.endw
	ret
main endp
bubble proc
	push ebp
	mov ebp,esp
	mov esi,[ebp+12]
	mov edi,esi
	mov ecx,[ebp+8]
	dec ecx
	.while ecx>0
		mov esi,edi
		mov ebx,ecx
		.while(ebx>0)
			mov eax,[esi]
			cmp eax,[esi+4]
			jl next
			xchg eax,[esi+4]
			mov [esi],eax
		next:
			add esi,4
			dec ebx
		.endw
			dec ecx
	.endw
	pop ebp
	ret 2*4
bubble endp
end main
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值