SCAU 汇编实验四

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。
先判断输入的第一个字符,是负号则用符号标记FLAG记录一下。不是负号则说明输入的是数字。开始判断数字字符的合法范围。

代码:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值