49703100.doc - 40 - 作者:User
MOV AX, 4321H CALL HTOA RET
MAIN ENDP ;主程序部分结束 ;-------------------------------------------------------------------- HTOA PROC NEAR ;HTOA子程序
CMP AX, 15 JLE B1 PUSH AX PUSH BP MOV BP, SP
MOV BX, [BP+2] AND BX, 000FH MOV [BP+2], BX POP BP MOV CL, 4 SHR AX, CL CALL HTOA POP BP
B1: ADD AL, 30H
CMP AL, 3AH JL PRINTIT ADD AL, 7H
PRINTIT: MOV DL, AL
MOV AH, 2 INT 21H RET
HOTA ENDP ;HOTA子程序结束 ;-------------------------------------------------------------------- CODE ENDS ;代码段结束 ;******************************************
END START ;程序结束
答:堆栈最满时各单元的地址及内容如右上图所示:
0500:00EC :00EE 返回POP BP地址 0003H :00F0 :00F2 返回POP BP地址 0002H :00F4 :00F6 返回POP BP地址 0001H :00F8 :00FA 主程序返回地址 0000 :00FC (DS) :00FE
00EE SP:
6.4 题堆栈最满时各单元
的地址及内容
6.5 下面是一个程序清单,请在下面的图中填入此程序执行过程中的堆栈变化。
;*************************
0000 STACKSG SEGMENT 0000 20 [. DW 32 DUP (?)
? ? ? ?
]
0040 STACKSG ENDS
;*************************
0000 CODESG SEGMENT PARA ?CODE‘
;--------------------------------------
0000 BEGIN PROC FAR
ASSUME CS: CODESG, SS: STACKSG
0000 1E PUSH DS 0001 2B C0 SUB AX, AX 0003 50 PUSH AX 0004 E8 0008 R CALL B10
;--------------------------------------
0007 CB RET 0008 BEGIN ENDP
;--------------------------------------
0008 B10 PROC 0008 E8 000C R CALL C10
;--------------------------------------
000B C3 RET
49703100.doc - 41 - 作者:User
000C
B10 ENDP
;--------------------------------------
000C C10 PROC
;--------------------------------------
000C C3 RET 000D C10 ENDP
;--------------------------------------
000D CODESG ENDS
;*************************
END BEGIN
答:程序执行过程中的堆栈变化如下图所示。
偏移地址 堆栈 ( 0016H ) ( 0016H ) ( 0016H ) ( 0016H )
( 0018H ) ( 0018H ) ( 0018H ) ( 0018H ) ( 001AH ) ( 001AH ) ( 001AH ) ( 001AH ) 0007 ( 001CH ) ( 001CH ) ( 001CH ) 0000 ( 001CH ) 0000 ( 001EH ) ( 001EH ) (DS) ( 001EH ) (DS) ( 001EH ) (DS) ( 0020H ) ( 0020H ) ( 0020H ) ( 0020H ) SP: 0020H 001EH 001CH 001AH
BEGIN PUSH DS PUSH AX CALL B10
( 0016H ) ( 0016H ) ( 0016H ) ( 0016H ) ( 0018H ) 000B ( 0018H ) 000B ( 0018H ) 000B ( 0018H ) 000B ( 001AH ) 0007 ( 001AH ) 0007 ( 001AH ) 0007 ( 001AH ) 0007 ( 001CH ) 0000 ( 001CH ) 0000 ( 001CH ) 0000 ( 001CH ) 0000 ( 001EH ) (DS) ( 001EH ) (DS) ( 001EH ) (DS) ( 001EH ) (DS) ( 0020H ) ( 0020H ) ( 0020H ) ( 0020H ) 001AH 001CH 0020H SP: 0018H 6.6 写一段子程序SKIPLINES,完成输出空行的功能。空出的行数在AX寄存器中。
答:程序如下:
CSEG SEGMENT SKIPLINES PROC FAR
ASSUME CS: CSEG
BEGIN: PUSH CX
PUSH DX MOV CX, AX
DISP: MOV DL, 0DH ;显示回车换行,即输出空行
MOV AH, 2 ;显示一个字符的DOS调用 INT 21H
MOV DL, 0AH MOV AH, 2 ;显示一个字符的DOS调用 INT 21H LOOP DISP POP DX POP CX RET
SKIPLINES ENDP
END
6.7 设有10个学生的成绩分别是76,69,84,90,73,88,99,63,100和80分。试编制一个子程
序统计60~69分,70~79分,80~89分,90~99分和100分的人数,分别存放到S6,S7,S8,S9和S10单元中。 答:程序如下:
DSEG SEGMENT
RECORD DW 76,69,84,90,73,88,99,63,100,80 S6 DW 0
49703100.doc - 42 - 作者:User
S7 DW 0 S8 DW 0 S9 DW 0 S10 DW 0 DSEG ENDS
;****************************************** CSEG SEGMENT MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX PUSH AX
MOV AX, DSEG MOV DS, AX ;给DS赋值
BEGIN: MOV CX, 10
CALL COUNT
┇ ;后续程序 RET
MAIN ENDP
;-------------------------------------------------------------------------- COUNT PROC NEAR ;成绩统计子程序
MOV SI, 0
NEXT: MOV AX, RECORD[SI]
MOV BX, 10 ;以下5句是根据成绩计算相对S6的地址变化量 DIV BL ;计算公式为:((成绩)/10-6)*2送(BX) MOV BL, AL ;此时(BH)保持为0不变 SUB BX, 6 ;应为只统计60分以上成绩 SAL BX, 1 ;(BX)*2 INC S6[BX] ;S6是S6,S7,S8,S9和S10单元的首地址 ADD SI, 2 LOOP NEXT RET
COUNT ENDP ;COUNT子程序结束 ;-------------------------------------------------------------------------- CSEG ENDS ;以上定义代码段 ;******************************************
END START
6.8 编写一个有主程序和子程序结构的程序模块。子程序的参数是一个N字节数组的首地址TABLE,
数N及字符CHAR。要求在N字节数组中查找字符CHAR,并记录该字符出现的次数。主程序则要求从键盘接收一串字符以建立字节数组TABLE,并逐个显示从键盘输入的每个字符CHAR以及它在TABLE数组中出现的次数。(为简化起见,假设出现次数≤15,可以用16进制形式把它显示出来。)
答:程序如下:
DSEG SEGMENT TABLE DB 255 DUP (?) N DW 255 CHAR DB ? CHAR_N DB 0 ;用于记录CHAR出现的次数 CRLF DB 0DH, 0AH, ?$‘ DSEG ENDS ;以上定义数据段 ;****************************************** STACK SEGMENT
DW 100 DUP (?)
TOS LABEL WORD STACK ENDS ;以上定义堆栈段
49703100.doc - 43 - 作者:User
;****************************************** CSEG SEGMENT MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG, SS: STACK
START: MOV AX, STACK
MOV SS, AX ;给SS赋值 MOV SP, OFFSET TOS ;给SP赋值 PUSH DS ;设置返回DOS SUB AX, AX PUSH AX
MOV AX, DSEG MOV DS, AX ;给DS赋值
BEGIN: MOV BX, 0
MOV CX, 255 ;最多输入255个字符
INPUT: MOV AH, 1 ;从键盘接收一个字符的DOS功能调用
INT 21H CMP AL, 0DH ;输入回车符结束输入 JZ IN_N
MOV TABLE [BX], AL INC BX LOOP INPUT
IN_N: MOV N, BX ;TABLE数组中的字符个数送N
CALL DISP_CRLF
IN_CHAR: MOV AH, 1 ;从键盘接收一个字符并回显的DOS功能调用
INT 21H CMP AL, 0DH ;输入回车符结束 JZ EXIT
MOV CHAR, AL ;输入的字符存入CHAR单元 CALL SEARCH ;调搜索字符子程序 MOV DL, ?:‘ ;显示―:‖,在字符CHAR(输入时回显)的后面 MOV AH, 2 ;显示一个字符 INT 21H
MOV DL, CHAR_N ;再显示CHAR出现的次数(次数≤15) AND DL, 0FH ADD DL, 30H CMP DL, 39H JBE NEXT ADD DL, 07H ;是A~F
NEXT: MOV AH, 2 ;显示一个字符
INT 21H
CALL DISP_CRLF JMP SHORT IN_CHAR
EXIT: RET MAIN ENDP
;-------------------------------------------------------------------------- SEARCH PROC NEAR ;搜索字符子程序
MOV SI, 0 MOV CX, N
MOV CHAR_N, 0 MOV AL, CHAR
ROTATE: CMP AL, TABLE [SI]
JNZ ROTATE1 INC CHAR_N ;搜索到字符,则出现次数+1
ROTATE1: INC SI
LOOP ROTATE RET