汇编语言设计—实验五(5.10-5.12)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值