实验四 子程序设计
一、实验目的
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