实验7 子程序

一、实验目的
掌握子程序的设计方法;理解子程序调用与返回指令的执行过程及堆栈的变化情况;掌握子程序调用过程中主程序与子程序间的参数传递方式,掌握现场的保护与恢复方法。
二、实验题
1.下面程序返回前, bx中的值是多少?

assume cs:code
code segment
start: mov ax,1
mov cx,3
call s
mov bx, ax ; (bx)=?
mov ax, 4c00h
int 21h
s: add ax, ax
loop s
ret
code ends
end start

分析:从调试页面知,程序返回前BX的值为8,也就是执行了三次 add ax,ax,然后将ax的值赋给BX。
2. 设计一个子程序,根据提供的N来计算N的3次方。

CODES SEGMENT
ASSUME CS:CODES
START:MOV AX,2
MOV bx,ax
MOV CX,2
CALL S
MOV BX,AX
MOV AX,4C00H
INT 21H
S:mul bx
loop s
RET
CODES ENDS
END START

  1. 现有一子程序divOverFlow的功能是进行不会除法溢出的除法运算:
    Y=1000000 DX AX Y/10=100000 div
    ;输入参数:被除数(高16位在DX中,低16位在AX中)、除数(在CX中)
    ;输出:商(高16位在DX中,低16位在AX中)、余数(在CX中)
divOverFlow proc near
push ax
mov ax, dx
mov dx,0
div cx ;此时AX里是公式加法左边的结果
mov bx, ax ;保存到BX中
pop ax
div cx
mov cx, dx
mov dx, bx
ret
divOverFlow endp

现在利用该子程序把数据段中的数据输出到屏幕上。

DATAS SEGMENT
DATAX DD 10000001’ ‘0’ ‘0
DATAS ENDS
DATA SEGMENT
ARRAY DD 1000000
DATA ENDS
CODE SEGMENT
ASSUME DS: DATA, CS: CODE
START:
MOV AX, DATA
MOV DS, AX
MOV SI, WORD PTR ARRAY[0] ;ARRAY低16位
MOV DI, WORD PTR ARRAY[2] ;ARRAY高16位
MOV BP, 0 ;将被输出的字符长度
func:
MOV AX, SI ;被除数
MOV DX, DI ;被除数
MOV CX, 10 ;除数10
CALL divOverFlow ;除法调用
MOV SI, AX ;更新SI,DI
MOV DI, DX
push CX ;入栈当前余数
ADD BP, 1 ;字符长度加1
;当商不为零时重复执行func
CMP SI, 0
JNZ func
CMP DI, 0
JNZ func
MOV CX, BP ;设置循环次数
flag:
pop DX
CALL show
loop flag
;执行完毕退出程序
MOV AH, 4CH
INT 21H
show: ;显示数字DL ,占用AX,DX寄存器
ADD DL, 30H
MOV AH, 2
INT 21H
RET
;占用AX,BX,CX,DX寄存器
;输入参数:被除数(高16位在DX中,低16位在AX中)、除数(在CX中)
;输出:商(高16位在DX中,低16位在AX中)、余数(在CX中)
divOverFlow proc near
PUSH AX
MOV AX, DX
MOV DX, 0
DIV CX ;此时AX里是公式加法左边的结果
MOV BX, AX ;保存到BX中
POP AX
DIV CX
MOV CX, DX
MOV DX, BX
RET
divOverFlow endp
CODE ENDS
END START

  1. 在第3题的基础上,把数据段中的数组输出到屏幕上。
DATAS SEGMENT
ARRAY DD 1234,56, 100, 5,89535
DATAS ENDS
DATA SEGMENT
ARRAY DD 1234 , 789 , 654321 , 10086 , 2222 ;待显示的数组
DATA ENDS
CODE SEGMENT
ASSUME DS: DATA, CS: CODE
START:
MOV AX, DATA
MOV DS, AX
MOV CX, 5 ;数组大小
MOV BP, 0 ;数组指针
change:
MOV SI, WORD PTR ARRAY[BP+0] ;ARRAY[BP]低16位
MOV DI, WORD PTR ARRAY[BP+2] ;ARRAY[BP]高16位
CALL func ;显示该数字
ADD BP, 4
MOV DL, ' '
SUB DL, 30H
CALL show ;显示分隔符
loop change;循环显示剩余数字
JMP exit ;程序结束
func:
;先保存数据
push AX
push BX
push CX
push DX
push BP
;将被输出的字符长度
MOV BP, 0
MOV AX, SI;被除数
MOV DX, DI;被除数
flag1:
MOV CX, 10;除数
CALL divOverFlow
push CX ;入栈当前余数
ADD BP, 1 ;字符长度加1
;当商不为零时重复执行func
CMP AX, 0
JNZ flag1
CMP DX, 0
JNZ flag1
MOV CX, BP ;设置循环次数
flag2:
pop DX
CALL show
loop flag2
;恢复数据
pop BP
pop DX
pop CX
pop BX
pop AX
;func函数结束返回
ret
exit: ;执行完毕退出程序
MOV AH, 4CH
INT 21H
show: ;显示数字DL
push AX
push DX
ADD DL, 30H
MOV AH, 2
INT 21H
pop DX
pop AX
RET
;输入参数:被除数(高16位在DX中,低16位在AX中)、除数(在CX中)
;输出:商(高16位在DX中,低16位在AX中)、余数(在CX中)
divOverFlow proc near
PUSH AX
MOV AX, DX
MOV DX, 0
DIV CX ;此时AX里是公式加法左边的结果
MOV BX, AX ;保存到BX中
POP AX
DIV CX
MOV CX, DX
MOV DX, BX
RET
divOverFlow endp
CODE ENDS
END START

三 实验报告
要求: 1.每步操作过程及所用指令;2.用截图方式反应指令执行前后的相关寄存器或存储单元内容的变化,并对所得结果进行分析。


__EOF__

本文作者DeepBrainBoy
本文链接https://www.cnblogs.com/tccjx/p/16362393.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   TCcjx  阅读(445)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示

喜欢请打赏

扫描二维码打赏

支付宝打赏