实验四
1、输入 5 位以内的八进制数,存入 BX 中。
算法分析:
代码:
DATAS SEGMENT
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
DB 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 AX,STACKS
MOV SS,AX
MOV SP,TOP
XOR BX,BX
MOV CX,5
;算法核心部分;
XOR AX,AX
L1: MOV AH,1
INT 21H
;判断合法性
CMP AL,0DH
JE L4 ;回车结束输入;
CMP AL,30H
JB L1
CMP AL,37H
JA L1
SUB AL,30H ;转成数字
PUSH CX
MOV CL,3
SHL BX,CL ;等价于把原BX中的数字乘以8(2的3次方)
AND AX,7
ADD BX,AX ;这里不能用BL,因为BL可能产生加法进位
POP CX
LOOP L1
;算法核心部分;
L4: MOV AH,4CH
INT 21H
CODES ENDS
END START
2、输入两个字数据(16 位的数)X,Y,计算 Z=X+Y,并把 Z 的结果显示出来。
**算法分析:**通过调试了。我假设是以二进制形式输入。
代码:
DATAS SEGMENT
X DW 0
Y DW 0
Z DW 0
DATAS ENDS
STACKS SEGMENT
DB 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 AX,STACKS
MOV SS,AX
MOV SP,TOP
XOR DX,DX
MOV CX,16;假设是二进制
L1: MOV AH,1
INT 21H
CMP AL,0DH
JE NEXT
SUB AL,30H;转数字
SHR AL,1
RCL DX,1
LOOP L1
NEXT: MOV X,DX
XOR DX,DX
MOV CX,16;假设是二进制
L2: MOV AH,1
INT 21H
CMP AL,0DH
JE FINISH
SUB AL,30H
SHR AL,1
RCL DX,1
LOOP L2
FINISH: MOV Y,DX
MOV DX,X
MOV BX,Y
ADD BX,DX ;结果存入BX
MOV CX,16
L4: MOV DX,30H
SHL BX,1
ADC DL,0
MOV AH,2
INT 21H
LOOP L4
MOV AH,4CH
INT 21H
CODES ENDS
END START
3、输入一个有符号的十进制数,并以十六进制输出。
算法分析:
符号用变量记录一下,其他数字直接当成无符号数存入BX。注意:这种方法BX可以表示的数字范围为-65535——65535。
代码:
DATAS SEGMENT
FLAG DB 0 ;符号位标记,0代表正号,1代表负号
RETYPE DB "retype please!",0DH,0AH,24H
DATAS ENDS
STACKS SEGMENT
DB 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 AX,STACKS
MOV SS,AX
MOV SP,TOP
XOR BX,BX
XOR DX,DX
JMP L1
AGAIN:
XOR BX,BX
XOR DX,DX ;清除上一次错误输入的所有内容
LEA DX,RETYPE
MOV AH,9
INT 21H
;输入符号位
L1: MOV AH,1
INT 21H
CMP AL,'-'
JNE FIRST ;非负号则保持FLAG的值为0;说明第一个输入的是数字
MOV FLAG,1;是负号则修改FLAG的值
;开始输入数字
L2: MOV AH,1
INT 21H
FIRST: ;单个数字合法性
CMP AL,0DH
JE DISP ;结束输入
CMP AL,'0'
JB AGAIN
CMP AL,'9'
JA AGAIN
SUB AL,30H ;转数字
AND AX,0FH
XCHG AX,BX ;为乘法做准备
MOV SI,10
MUL SI
JC AGAIN
ADD BX,AX
JC AGAIN
LOOP L2
DISP:
CMP FLAG,0
JE L3 ;正数不输出符号
;输出负号
MOV DL,'-'
MOV AH,2
INT 21H
L3: MOV CX,4;剩下的数字可分为4组(4次循环)
L4: PUSH CX ;因为下面的指令需要用到CX,这里进栈保存一下循环的次数
;算法核心部分;
MOV CL,4
ROL BX,CL
MOV DX,BX ;保留BX内数据
AND DL,15 ;获取BX最后四位位向量
;(但是!!!单个十六进制数字
;有数字形式还有字母形式,所以需要判别,
;是转化为数字字符还是字母字符)
CMP DL,0AH;判断是否大于等于10
JGE L5
ADD DL,30H;小于10说明应转化为数字字符
JMP L6
L5: ADD DL,37H;大于等于10说明应转化为字母字符
;算法核心部分
L6: MOV AH,2
INT 21H
POP CX ;恢复循环次数
LOOP L4
MOV AH,4CH
INT 21H
CODES ENDS
END START
5.4 试编写一程序,要求比较两个字符串 STRING1 和 STRING2 所含字符是否完全相同,若相同则显示‘MATCH’, 若不相同则显示‘NO MATCH’。
**算法:**简单,不想分析。
代码:
DATAS SEGMENT
STR1 DB "HELLO!"
LEN1 DB $-STR1 ;字符串的长度
STR2 DB "HELLO!"
LEN2 DB $-STR2 ;字符串的长度
I DB 0 ;字符串的偏移量,相当于指针
DSTR1 DB "MATCH",0DH,0AH,24H
DSTR2 DB "NO MATCH",0DH,0AH,24H
DATAS ENDS
STACKS SEGMENT
DB 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 AX,STACKS
MOV SS,AX
MOV SP,TOP
XOR CX,CX
MOV CL,LEN1
MOV BL,LEN1
CMP BL,LEN2
JNE DISP ;两串长度不相等直接不匹配
L1:
LEA BX,STR1
LEA SI,STR2
XOR DX,DX
MOV DL,I ;主要是下面的SI不能直接加字节I
ADD BX,DX
ADD SI,DX
ADD I,1 ;字符串的指针加1
MOV DX,[BX]
CMP DX,[SI]
JNE DISP
LOOP L1
DISP:CMP CX,0
JE YES ;CX不为0有两种情况
;1、循环未结束,发现了不匹配的字符
;2、两串长度不等。我故意设了CX初始值不为0
;不匹配
NO: LEA DX,DSTR2
MOV AH,9
INT 21H
JMP FINISH
;匹配
YES:LEA DX,DSTR1
MOV AH,9
INT 21H
FINISH:
MOV AH,4CH
INT 21H
CODES ENDS
END START
5.10 设有一段英文,其字符变量名为 ENG,并以$字符结束。试编写一程序,查找单词 SUN在该文中的出现次数,并以格式“SUN : xxxx”显示出次数
算法: 大部分结果没问题,但sunsusun结果错误,而sunsuasun结果正确。怀疑是匹配失败时指针没滑到我想要的位置。
代码:
DATAS SEGMENT
ENG DB "SUNSUNSUNSUN",24H ;目标串
FILL DB 24H,24H ;用于防止目标串指针越界比较时发生错误
STR1 DB "SUN" ;源串
DSTR1 DB "SUN:" ;该串内容加上count就是显示结果
COUNT DB 0 ;记录sun出现的次数
DATAS ENDS
STACKS SEGMENT
DB 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
MOV AX,STACKS
MOV SS,AX
MOV SP,TOP
CLD
LEA DI,ENG
;;算法核心;
;直接拿"SUN"在字符串ENG中匹配,用COUNT记录它出现的次数;
;变量说明:DI指向目标串下一个待比较的字符,SI指向源串下一个待比较的字符
L1: LEA SI,STR1
MOV CX,3
;扫描是否有SUN匹配
REPZ CMPSB
JNE L2
JCXZ ADD1 ;ZF=0&&CX=0,说明完全匹配
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
CODES ENDS
END START