5.10 设有一段英文,其字符变量名为 ENG,并以$字符结束。试编写一程序,查对单词 SUN
在该文中的出现次数,并以格式“SUN:xxxx”显示出次数。
S1 SEGMENT STACK
DW 30H DUP(0)
TOP LABEL WORD
S1 ENDS
S2 SEGMENT
ENG DB 'SUNABDSUNJDJKKL$' ; 测试字符串(包含3个SUN)
STR1 DB 'SUN'
DSTR1 DB 'SUN' ;该串加上count就是显示结果
COUNT DB 0 ; 计数器初始化为0
S2 ENDS
S3 SEGMENT
ASSUME CS:S3, DS:S2, SS:S1
MAIN PROC FAR
MOV AX, S1
MOV SS, AX
LEA SP, TOP
MOV AX, S2 ;数据段
MOV DS, AX
MOV ES, AX
; 初始化搜索
MOV DI, OFFSET ENG ; SI指向字符串起始
CLD ;DF=0
L1: LEA SI,STR1
;扫描是否有SUN匹配
MOV CX,3
REPZ CMPSB
JNE L2
JCXZ ADD1 ;说明完全匹配
JMP L2 ;说明不完全匹配
ADD1:
INC COUNT ;SUN匹配一次
L2: XOR BX,BX
MOV BL,ES:[DI]
CMP BL,24H
JE DISP
LOOP L1
DISP:
MOV DL,0DH
MOV AH,2
INT 21H
MOV AX,30H
ADD COUNT,AL
LEA BX,DSTR1
MOV CX,5
L3: MOV DX,[BX]
MOV AH,2
ADD BX,1
INT 21H
LOOP L3
; 程序结束
MOV AH, 4CH
INT 21H
MAIN ENDP
S3 ENDS
END MAIN
5.11 从键盘输入一系列以$为结束符的字符串,然后对其中的非数字字符计数,并显示出计
数结果。
DATAS SEGMENT
MAXL DB 100
RLEN DB ?
STR1 DB 100 DUP(0),0DH,0AH,'$'
SUM DB 0
DATAS ENDS
STACKS SEGMENT
DW 30H DUP(0)
TOP LABEL WORD
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
MAIN PROC FAR
MOV AX,DATAS
MOV DS,AX
MOV AX,STACKS
MOV SS,AX
LEA SP,TOP
MOV AH,0AH
LEA DX,MAXL
INT 21H
LEA SI,STR1+2 ;不是STR1+2
MOV CX,0
;如果以下写法,其中RLEN包含0DH,0AH,这两个字符也会被处理进去
;MOV CL,RLEN
;MOV CH,0
L1: ;PUSH CX
MOV AL,[SI]
CMP AL,0DH ;用回车符判断,而不是$
;CMP AL,'$' ;输入12gh 输出4,会包含0DH、0AH
JE L2 ;遇到0DH直接跳转
CMP AL,'0'
JB EQUL
CMP AL,'9'
JBE NEXT ;说明是数字
EQUL:
INC SUM
NEXT:
INC SI
;POP CX
LOOP L1
L2: MOV AH,02H
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV DL,0
OUT_PUT:
MOV DL,SUM
ADD DL,30H
MOV AH,02H
INT 21H
EXIT:
MOV AH,4CH
INT 21H
MAIN ENDP
CODES ENDS
END MAIN
5.12 有一个首地址为 MEM 的 100D 字数组,试编制程序删除数组中所有为 0 的项,并将后
续项向前压缩,最后将数组的剩余部分补上 0。
DATAS SEGMENT
MEM DW 1,2,3,9,0,3,0,1,9,0,4,5,0,6 ;14个
NUM EQU ($-MEM)/2 ;求解数组大小
DATAS ENDS
STACKS SEGMENT
DW 30H DUP(0)
TOP LABEL WORD
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV ES,AX
LEA DI,MEM
LEA SI,MEM
;PUSH DI
MOV AX,STACKS
MOV SS,AX
LEA SP,TOP
MOV CX,NUM ;赋值数组长度
L1: PUSH CX
LODSW ;AX=DS:[SI],SI+=2
CMP AX,0 ;如果当前数字为0,则跳过DI的移动;不为0,就把SI赋值给DI
JE NEXT
STOSW ;ES:[DI]=AX,DI+=2
NEXT:
POP CX
LOOP L1
;怎么计算还要补多少位数字
MOV AX,DI ;记录当前压缩后的数组内存地址
;POP DI ;可能因为循环次数过多,然后破环DI的值,所以最好直接取OFFSET
SUB AX,OFFSET MEM ;用当前压缩后的数组减初始数组的开头
SHR AX,1 ;转化为字的个数,AX/=2
MOV CX,NUM
SUB CX,AX ;剩余要补0的个数
ZERO_OP:;补0操作
CLD ;DF=0,向下填充
MOV AX,0
REP STOSW
MOV CX,NUM
LEA DI,MEM
PRINT:;输出验证
PUSH CX
MOV DX,ES:[DI]
ADD DX,30H ;将数字0转化为字符'0'
MOV AH,02H
INT 21H
ADD DI,2
POP CX
LOOP PRINT
EXIT:
MOV AH,4CH
INT 21H
CODES ENDS
END START

被折叠的 条评论
为什么被折叠?



