汇编实验们

汇编是真的很难啊,我哭死,写的我头疼,给老师演示的时候感觉我左脑是水,右脑是面粉,摇一摇就满脑子的浆糊了。垃圾代码如下,如有问题,欢迎指出~


一、实验1

对以下数组10,267,9,0,68,-516,3,85,OFCH,101,-32
1)计算数组中正数累加结果保存到变量result。
2)计算数组到负数为止的非负数累加结果保存到变量。
3)计算数组中零,正,负数,奇,偶数元素个数分别保存。
4)查找数组中最小元素,绝对值最大元素,排序数组。要求菜单提示选择,调试查看运行结果。

代码如下

.MODEL SMALL
.STACK 4096
.DATA
	ARRAY DW 10,267,9,0,68,-516,3,85,101,-32,0FCH;数组的内容
	RESULT DW 0		;计算正数之和
	SUM DW 0		;计算数组到负数为止的非负数累加结果保存到变量SUM
	NUMZERO DB 0	;0的个数
	NUMFUSHU DB 0	;负数个数
	NUMZHENG DB 0	;正数个数
	NUMJISHU DB 0	;奇数个数
	NUMOUSHU DB 0	;偶数个数
	MINNUM DW 0		;最小的元素
	MAXNUM DW 0		;绝对值最大的元素
	
	
	STRING0 DB 0DH,0AH,'Please input a number:',0DH,0AH,'$'
	
	STRING1 DB 0DH,0AH,'If you input 1,we will add zhengshu.','$'
	STRING2 DB 0DH,0AH,'If you input 2,we will add zhenshu till a fushu.','$'
	STRING3 DB 0DH,0AH,'If you input 3,we will count the number of zhengshu,fushu,zero,jishu and oushu','$'
	STRING4 DB 0DH,0AH,'If you input 4,we will seek the smallest num and the biggest num ,then paixu.','$'
	
	STRING5 DB 0DH,0AH,'We add the sum in RESULT!',0DH,0AH,'$'
	STRING6 DB 0DH,0AH,'We add this numbers in SUM!',0DH,0AH,'$'
	STRING7 DB 0DH,0AH,'Counting positive and negative numbers has ended!','$'
	STRING8 DB 0DH,0AH,'The counting of odd even numbers has ended!',0DH,0AH,'$'
	STRING9 DB 0DH,0AH,'The number of jishu is:',0DH,0AH,'$'	
	STRING10 DB 'The number of oushu is:',0DH,0AH,'$'	
	STRING11 DB 0DH,0AH,'The number of zhengshu is:',0DH,0AH,'$'	
	STRING12 DB 0DH,0AH,'The number of fushu is:',0DH,0AH,'$'	
	STRING13 DB 0DH,0AH,'The number of 0 is:',0DH,0AH,'$'	
	STRING14 DB 0DH,0AH,'SORT SUCCESS!',0DH,0AH,'$'	
	
	
.CODE
MAIN PROC FAR
	MOV AX,@DATA
	MOV DS,AX
	
;-----------------------	
	;输出一串提示	
	LEA DX,STRING1
	MOV AH,09H
    INT 21H
    
    LEA DX,STRING2
	MOV AH,09H
    INT 21H
    
    LEA DX,STRING3
	MOV AH,09H
    INT 21H
    
    LEA DX,STRING4
	MOV AH,09H
    INT 21H
    
    LEA DX,STRING0
	MOV AH,09H
    INT 21H;输出一串提示
    
    MOV AH,1
	INT 21H;键盘输入并回显
	
	MOV DL,AL;输入的数字在AL中,赋值给DL
	CMP DL,'1';判断是否为1
	JE HANSHU1;如果是1就进入函数1

	MOV DL,AL;输入的数字在AL中,赋值给DL
	CMP DL,'2';判断是否为2
	JE HANSHU2;如果是2就进入函数2
	
	MOV DL,AL;输入的数字在AL中,赋值给DL
	CMP DL,'3';判断是否为3
	JE HANSHU3;如果是3就进入函数3
	
	MOV DL,AL;输入的数字在AL中,赋值给DL
	CMP DL,'4';判断是否为4
	JE HANSHU4;如果是4就进入函数4

	MOV AH,4CH;返回MOS-DOS窗口
	INT 21H

MAIN ENDP


;函数1-----计算正数之和
HANSHU1 PROC NEAR

	LEA DX,STRING5
	MOV AH,09H
    INT 21H;输出一串提示,开始计算RESULT
    
    MOV CX,LENGTHOF ARRAY	;数组的长度    
    MOV SI,OFFSET ARRAY		;偏移量
    MOV AX,0				;计算AX,初始化为0
    MOV BX,0				;先存在BX里面
 	LP:
		MOV AX,[SI] ;[SI]中的数的符号位和1000 0000B相与,如果结果不是0,那么代表是负数,反之,正数
	    CMP AX,8000H
	    JA NEXT
	    ADD BX,AX
	NEXT:
	    ADD SI,TYPE ARRAY	;每次增加偏移量
	    LOOP LP  
    	MOV RESULT,BX		;AX中的值赋值给RESULT
    	mov ax,bx
    CALL OUTPUT1
    CALL MAIN
	RET
HANSHU1 ENDP




;函数2-----计算数组到负数为止的非负数累加结果保存到变量SUM
HANSHU2 PROC NEAR
	
	LEA DX,STRING6
	MOV AH,09H
    INT 21H;输出一串提示,开始计算SUM
	
	MOV CX,LENGTHOF ARRAY	;数组的长度    
    MOV SI,OFFSET ARRAY		;偏移量
    MOV AX,0				;计算AX,初始化为0
    MOV BX,0				;结果先放在BX里面
	
	LP:
		MOV AX,[SI] 	;[SI]中的数的符号位和1000 0000B相与,如果结果不是0,那么代表是负数,反之,正数=0
	    CMP AX,8000H
	    JA NEXT				;结果不为0跳转,即负数跳转
	    ADD BX,AX
	    MOV SUM,BX
	    ADD SI,TYPE ARRAY	;每次增加偏移量
	    LOOP LP	
	    
NEXT:
	mov ax,bx
	CALL OUTPUT1
	CALL MAIN
	
	RET
HANSHU2 ENDP


;函数3--------计算数组中零,,负数,,偶数元素个数分别保存。
HANSHU3 PROC NEAR
	LEA DX,STRING7
	MOV AH,09H
    INT 21H					;输出一串提示,开始计算NUMZERO,NUMFUSHU,NUMZHENG
    
    
    MOV SI,OFFSET ARRAY		;偏移量
    MOV CX,LENGTHOF ARRAY	;用于计数,总共11FIRST:						;比较计数板块
	    CMP CX,0				;比较次数是否达到最后了
	    JE OUTPUT				;相等的时候跳转到输出板块
	    	
	    MOV AX,[SI]				;接收数据
	    
	    CMP AX,0				;先判断是否是零
	    JE ZERONUM				;表示为零
	    
	      	
	    TEST AX,8000H
	    JZ PNUM					;等于0的时候跳转
	    JA NNUM					;无符号大于跳转
	 
	ZERONUM:
		ADD NUMZERO,1
		JMP OVER;每一次输出收尾
	NNUM:
		ADD NUMFUSHU,1
		JMP OVER
	PNUM:
		ADD NUMZHENG,1
		JMP OVER
    
	OVER:
		DEC CX;计数
		ADD SI,2;偏移量
		JMP FIRST;回到起点
	    
	OUTPUT:;输出板块bx/cx不能动,保留着计数
		LEA DX, string11;正数的输入提示                                       
	    MOV AH, 09H							 
	    INT 21H
    
	    ADD NUMZHENG,30H
	    MOV DL,NUMZHENG
	    MOV AH,2
	    INT 21H
 
    
	    LEA DX, string12;负数的输入提示                                       
	    MOV AH, 09H							 
	   	INT 21H
	    
	    ADD NUMFUSHU,30H
	   	MOV DL,NUMFUSHU
	    MOV AH,2
	    INT 21H
    
   
    
	    LEA DX, string13;零的输入提示                                       
	    MOV AH, 09H							 
	    INT 21H
    
	    ADD NUMZERO,30H
	    MOV DL,NUMZERO
	    MOV AH,2
	    INT 21H
	    
    

	CALL NUM
	RET
HANSHU3 ENDP



;函数3里面的一个函数-------计算奇数偶数元素的个数
NUM PROC NEAR
	LEA DX,STRING8
	MOV AH,09H
    INT 21H;输出一串提示,开始计算NUMJISHU,NUMOUSHU
    
    
    MOV BX,OFFSET ARRAY		;BXSI都可以做偏移量
    MOV DX,0				;DX=0
    MOV CX,LENGTHOF ARRAY	;CX是数组的长度
    
	NEXT:
		MOV AX,[BX]			
		TEST AX,1			;判断奇数偶数,最后一位为0是偶数,最后一位是1是奇数
		JNZ L1				;ZF不等于0就跳转,即奇数跳转
		INC DL				;DL+1
		JMP L2				;ZF=0,即偶数跳转

	L1:;奇数
		INC DH				;DH+1,奇数个数存在DH里面,偶数个数存在DL里面
							
	L2:;偶数
		ADD BX,TYPE ARRAY		
		LOOP NEXT
		
		MOV BX,DX			;DX=BX--->DL=BL,DH=BH		
		
		;输出奇数的个数		
		MOV DX,OFFSET STRING9
		MOV AH,09H
		INT 21H
		MOV DL,BH
		ADD DL,30H
		MOV AH,2H
		INT 21H
		
		;换行符
		MOV DL,0DH
		MOV AH,02H
		INT 21H
		
		;回车符
		MOV DL,0AH
		MOV AH,2H
		INT 21H
		
		;输出偶数的个数
		MOV DX,OFFSET STRING10
		MOV AH,09H
		INT 21H
		MOV DL,BL
		ADD DL,30H
		MOV AH,2H
		INT 21H
  
	
	CALL MAIN
	RET
NUM ENDP


;函数4--------查找最小元素,绝对值最大元素和数组排序
HANSHU4 PROC NEAR
	LEA DX,STRING4
	MOV AH,09H
    INT 21H				;输出一串提示,开始计算MINNUM,MAXNUM



		
	MOV BX,OFFSET ARRAY		; 设置指向数据区的指针
	MOV AX,[BX]; 
	MOV MAXNUM,AX	 			; 最大最小值都初始化成第1个数
	MOV MINNUM,AX
	MOV CL,LENGTHOF ARRAY               	; 数据个数
	A1:	
		MOV AX,[BX]            	; 从内存取数
		CMP AX,MAXNUM             	; 大于最大值MAX转去替换MAX
		JG  A2
		CMP AX,MINNUM
		JL A3                 ;   小于最小MIN转去替换MIN
		JMP A4
	A2:	
		MOV MAXNUM,AX
		JMP A4
	A3: 
		MOV MINNUM,AX
	A4: INC BX 
		LOOP A1     
	
	MOV AX,MAXNUM
	ADD AX,MINNUM
	TEST AX,8000H
		JA CHANGE
	CHANGE:
		MOV BX,MINNUM
		NEG BX
		MOV MAXNUM,BX


	CALL PAIXU

	
	RET
HANSHU4 ENDP




;函数PAIXU,是函数4里面的一个子函数,用来冒泡排序的

PAIXU PROC NEAR
	LEA DX,STRING14
	MOV AH,09H
    INT 21H
 	LEA DI, ARRAY
    MOV BL,LENGTHOF ARRAY 
	NEXT1: 
		MOV SI,DI 
       	MOV CL,BL
	NEXT2: 
		MOV AX,[SI]
       	INC SI
       	INC SI
       	CMP AX,[SI]
      	Jc  NEXT3   ;小于则不交换 
       	MOV DX,[SI] 
       	MOV [SI-2],DX
       	MOV [SI],AX
	NEXT3: 
		DEC CL 
       	JNZ NEXT2
       	DEC BL 
      	JNZ NEXT1
      	
      	CALL MAIN

    RET
PAIXU ENDP  
	

;多位输出函数
OUTPUT1 proc near
	
	;初始化变量
	mov cl,10;作为除数
	mov ch,0;用于计数便于后续出栈输出
	
divagain:;除法数字剥离部分
	cmp ax,0;判断是否已经除尽
		je divover
	inc ch;计数器加1
	div cl
	push ax;入栈,提取的时候取用ah部分,存储余数(低位优先)
	mov ah,0;调整ax
		jmp divagain;再次除法剥离数字
		
divover:;出栈输出部分
	cmp ch,0;判断数字是否已经出尽
		je outputover
	pop ax;取用ah部分
	mov dl,ah;输出部分
	add dl,30H
	mov ah,2
	int 21h
	dec ch
		jmp divover 
		
outputover:
	ret
OUTPUT1 endp
    

END

效果如下

汇编实验们_第1张图片
汇编实验们_第2张图片
汇编实验们_第3张图片
汇编实验们_第4张图片

二、实验2

对于100以内的整数判断是否是素数,如果是素数,十进制形式输出,每行输出10个数。


data segment
	text DB 'Prime numbers within 100 are:',0DH,0AH,'$'
	var1 DB 0,4 dup(0)
data ends
assume cs:code,ds:data

code segment
start:

	mov ax,data
	mov ds,ax
	
	mov dx,OFFSET text
	MOV AH,9H
	INT 21H		

mov cx,99
aa1:		;第一层循环
	mov ax,101
	sub ax,cx
	push cx
	call demo1	;判断ax是否为素数
	pop cx
loop aa1



	



demo1 proc	;判断ax是否为素数
mov cx,ax	;ax=2,
dec cx		;自减指令,cx=1



aa2:		;第二层循环
	push ax
	div cl			;ax%cl=ah
	cmp ah,0
	pop ax
	je aa2end		;if(i%j==0)break
loop aa2


aa2end:
cmp cx,1
jne demo1end
mov ah,0

mov dx,ax
call demo2		;输出多位数
demo1end:
ret
demo1 endp

demo2 proc	;输出多位数
push dx

;mov dx,1060
mov ax,dx
mov dx,0
;mov var1,0
again:
mov bx,10
div bx
inc var1[0]
mov bl,var1
mov bh,0
mov var1[bx],dl
mov dx,0
cmp ax,0
jne again
again1:
mov bl,var1
mov bh,0
mov dl,var1[bx]
add dl,30h
mov ah,2
int 21h

dec var1
mov al,var1
cmp al,0
jne again1
mov dl,9H		;制表符
mov ah,2
int 21h

pop dx
ret
demo2 endp

code ends
end start

效果如下

汇编实验们_第5张图片

三、实验3

计算输入两个数的最小公倍数和最大公约数

代码如下


;计算输入两个数的最小公倍数和最大公约数
.MODEL SMALL
.DATA
	
	NUMBER1         DW ?
	NUMBER2         DW ?
	BIGANS          DW ?		;最大公约数
	SMALLANS        DW ?		;最小公倍数
	
	INPUT1          DB 'input number1=$'
	INPUT2          DB 0dh,0ah,'input number2=$'
    BIGOUTPUT       DB 0DH,0AH,'BIGANS=$' 		;最大公约数
    SMALLOUTPUT     DB 0DH,0AH,'SMALLANS=$' 	;最小公倍数


.CODE



MAIN PROC FAR
	MOV AX,@DATA
	MOV DS,AX
;-----------------------以上是模板	
	;获取第一个数	
	LEA DX,INPUT1
	MOV AH,9
	INT 21H
	CALL SHURU			;打开输入
	MOV NUMBER1,BX		;BX中的值赋值给X
	
	;获取第二个数
	LEA DX,INPUT2
	MOV AH,9
	INT 21H
	CALL SHURU
	MOV NUMBER2, BX
	
	
	CALL GONGYUESHU
	MOV BX, BIGANS
	LEA DX,BIGOUTPUT
	MOV AH,9
	INT 21H
	CALL XIANSHI
	
	
	CALL GONGBEISHU
	MOV BX,SMALLANS
	LEA DX,SMALLOUTPUT
	MOV AH,9
	INT 21H
	CALL XIANSHI
	
	MOV AH, 4CH 
	INT 21H
	
MAIN ENDP


;输入数字到BX
SHURU PROC NEAR

		MOV BX,0		;初始化BX0
	S1: 
		MOV AH,1   		;键盘输入并回显
		INT 21H 	
		
		CMP AL, 0DH 	;输入是回车是结束
		JZ  EXIT		;标志位为0就跳转
		
		AND AX, 000FH   
		XCHG AX, BX   	;AXBX中的内容交换
		MOV CX, 10   	;初始化CX=10
		MUL CX      	;之前输入的数乘以10 加上新输得数..比如123先是 0*10+1 ->1*10+2 ->12*10+3
		ADD BX, AX  	;AXBX相加存入BXJMP S1			;继续输入
		
	EXIT:         		;输入了回车 退出
		;MOV DL, 0AH  	;换行
		MOV AH, 2		;显示输入字符
		INT 21H
	RET
SHURU ENDP



;显示BX中的数
XIANSHI PROC NEAR
		;MOV DL, 0AH  	;换行
		;MOV AH, 2
		;INT 21H
		
		MOV AX, BX   	;BX中的值给X     
		MOV BX, 10		;BX赋值成10
		MOV CX, 0		;CX赋值成0
	LET1:        		;将要显示的数除以10 把余数入栈
		MOV DX, 0     	;DX赋值成10
		INC CX   		;CX+1
		IDIV BX			;除以BX,除数为16位,则被除数为32位,商放在AX,余数放在DX
		PUSH DX			;余数入栈
		
		CMP AX, 0    	;商为0时结束
		JNZ LET1			
	LET2:        	
		POP AX       	;将商弹入 AX
		ADD AX, 3030H 	;商调整为ASCMOV DL, AL     	;显示商
		
		MOV AH, 2
		INT 21H
		LOOP LET2
	RET
XIANSHI ENDP


;求两个数的最大公约数其中BX是除数
GONGYUESHU PROC NEAR

		MOV BX, 1		;BX初始化为1
	SS1:
		MOV DX, 0		;DX初始化为0
		MOV AX, NUMBER1	;把其中一个数赋值给AX
		DIV BX			;除以BX,商在AX,余数在DX
		CMP DX, 0		;余数和0比较
		JNZ SS2    		;如果BX不能被整除 BX不是公约数 跳到SS2
		MOV DX, 0		;DX赋值给0
		MOV AX, NUMBER2	;AX赋值另一个数
		DIV BX			;这个数也除以BX
		CMP DX, 0		;余数和0比较
		JNZ SS2    		;如果BX不能被Y整除 BX不是公约数 跳到SS2
		MOV BIGANS,BX   	;如果既能被X整除又能被Y整除的值放到ans里面 
	
	SS2:      ;BX加到等于被除数的时候跳出 ..否则除数加1..判断BX+1是不是公约数..
		CMP BX,NUMBER1	;BX和第一个数比较  
		INC BX    		;BX+1
		JNZ SS1  		;如果BX!=这个数,就跳转
	RET				
GONGYUESHU ENDP


;最小公倍数就是XY在除以最大公约数...
GONGBEISHU PROC NEAR 
		MOV AX, NUMBER1		;将第一个数赋值给AX
		MUL NUMBER2			;乘以第二个数
		DIV BIGANS			;除以最大公约数,商在AX
		MOV SMALLANS,AX		;把商赋值给最小公倍数
		

		RET

GONGBEISHU ENDP
	

END


效果如下

汇编实验们_第6张图片

四、实验4

查找子串在字符串中出现的次数并去除
代码如下


.MODEL SMALL
.DATA
	;单词初始化只给8个字节
	WORD_LEN DB 8
	FACTWORD_LEN DB ?
	KEY_WORD DB 8 DUP(?)
	;句子给32个字节
	SENTENCE_LEN DB 32
	FACTSENTENCE_LEN DB ?
	SENTENCES DB 32 DUP(?)

	;输入的信息
	INPUT1 DB 'Enter the Keyword:$'
	INPUT2 DB 'Enter the Sentence:$'
	;输出的信息
	OUTPUT1 DB 'The number is:$'
	OUTPUT2 DB 'After that,the sentence is:$'
	OUTPUT DB 'No Match!$'
	
	NUM DB 0
	STRING DB ' '
	
.CODE


MAIN PROC NEAR
	MOV AX,@DATA
	MOV DS,AX
	
	
	;------------模板
	MOV ES,AX
	
	
	
	BEGIN:
		;输出信息
		
		MOV AH,09H
		LEA DX,INPUT2
		INT 21H
		
		
		MOV AH,0AH
		LEA DX,SENTENCE_LEN
		INT 21H
		CALL NEWLINE
		
		
		MOV AH,9H
		LEA DX,INPUT1
		INT 21H
		
		MOV AH,0AH		;输入到缓冲
		LEA DX,WORD_LEN
		INT 21H
		CALL NEWLINE
		
	
		MOV CH,FACTSENTENCE_LEN
		MOV CL,FACTWORD_LEN
		LEA DI,SENTENCES		;输入的句子在DIMOV BH,0				;BH=0
		
		
		ZBJ: 
			LEA SI,KEY_WORD		;单词放在SICMP CH,FACTWORD_LEN;正常情况下是ZF=0,CF=0
			JB LOOP3	       	;无符号小于则跳转,即句子的长度如果小于单词的长度,最后输出没有匹配
			MOV CL,FACTWORD_LEN	;CL赋值单词实际的长度
			MOV BL,0			;BL=0
		
		ISSAME:
			CMPSB				;把单词的第一个赋值给句子的第一个
			;也就是说,当单词这一位和句子的这一位不同,ZF=1
			JZ LOOP1			;ZF=0跳转
			JNZ LOOP2			;ZF=1跳转,单词和句子不匹配
		
		LOOP1:
			MOV BL,1			;BL=1
			DEC CH				;CH--,句子长度-1
			DEC CL				;CL--,单词长度-1
			JNZ ISSAME				;ZF=1跳转,
			MOV CL,FACTWORD_LEN
			ADD CL,CH
			MOV DL,SENTENCE_len
			mov cl,FACTWORD_LEN
      		add cl,ch
     	 	mov dl,FACTSENTENCE_LEN
      		sub dl,cl
      		;inc  dl
      		
      		MOV SI,DI
      		MOV CL,FACTWORD_LEN
      		n:	
      			
      			MOV AL,'-'
      			MOV [SI-1],AL
      			MOV DL,[SI-1]
      			DEC Cl
      			DEC SI
      			CMP Cl,0
      			JNZ N
      		
			ADD NUM,1
			
			MOV BH,1
			JMP ZBJ
      LOOP2:

      		CMP BL,1	;BL1比较,小于就是ZF=0
      		JZ PJ		;标志符为0就跳转
      		DEC CH		;CH--
      		JMP ZBJ		
      		
		PJ: 
			DEC DI		;句子的位置减一
			JMP ZBJ  	;跳转
     		
		loop3: 
		
			CMP BH,1		;BH=0-->ZF=0
			JZ QUIT			;ZF=0就跳转
			
			MOV AH,09H		;输出没有匹配到
			LEA DX,OUTPUT
			INT 21H
			CALL NEWLINE	;空一行
			
		
     		
		QUIT:
		
			MOV AH,09H
			LEA DX,OUTPUT1
			INT 21H
			MOV DL,NUM
			ADD DL,30H
			
			MOV AH,02H
			INT 21H
			
			CALL PRESENT
			;MOV AH,4CH
			;INT 21H
			
MAIN ENDP



;进入下一行再开始
NEWLINE PROC NEAR
	
	MOV DL,0DH
	MOV AH,02H
	INT 21H
	MOV DL,0AH
	MOV AH,02H
	INT 21H
	   
	RET
NEWLINE ENDP



PRESENT PROC NEAR
	
	CALL NEWLINE
	MOV AH,09H
	LEA DX,OUTPUT2
	INT 21H
	
	MOV CL,0
	
	LEA SI,SENTENCES
	M:
		MOV AL,[SI]
		CMP AL,'-'
		JZ X
		MOV DL,[SI]
		MOV AH,02H
		INT 21H
		INC SI
		Inc CL
		MOV BH,FACTSENTENCE_LEN
		CMP CL,BH
		JNZ M
		JZ EX
	X:
		INC SI
		Inc CL
		JMP M
	EX: 
		MOV AH,4CH
			INT 21H
	
	RET
	
	
PRESENT ENDP

END


效果如下

汇编实验们_第7张图片

你可能感兴趣的:(汇编,学习)