8086汇编语言(四) 冒泡排序等几个汇编程序

冒泡排序等几个汇编程序

1. 冒泡排序

冒泡排序

DATA SEGMENT WORD PUBLIC 'DATA'       
	ORG 00H					
	ARRAY_SIZE DW 5    		;待排序的数的个数
	NUMBER_ARRAY DW 100D, 64D, 79D, 22D, 113D	;待排序的数
	PRIVIOUS DW 00H			;用来存放冒牌排序中比较时的数
	LAST DW 00H				;用来存放冒牌排序中比较时的数
	TEN DB 10				;数字10, 用于分解一个数
DATA ENDS
EXTRA SEGMENT WORD PUBLIC 'EXTRA'
EXTRA ENDS
CODE SEGMENT WORD PUBLIC 'CODE'    
	INITIIALIZE PROC    	;用来初始化段寄存器的过程    
		MOV AX, EXTRA          
		MOV ES, AX              
		MOV AX, DATA        
		MOV DS, AX        
		RET    
	INITIIALIZE ENDP    
	TERMINATE PROC        	;用来退出程序的过程
		MOV AH, 4CH        
		INT 21H          	;因为程序直接退出, 可以不需要加RET
	RET    
	TERMINATE ENDP      
	PRINTLN PROC        	;换行的过程
		PUSH AX        		
		PUSH DX        		;过程中要用到这两个寄存器, 先把原来的值存到栈里
		MOV AH, 2        	;功能号2是字符显示
		MOV DL, 0DH        	;DL寄存器存放打印字符, 这里是0D是换行的意思
		INT 21H        		;中断操作, 进行打印字符
		MOV DL, 0AH        	;0A是光标指向第一个字符的意思
		INT 21H        		;中断操作
		POP DX        	
		POP AX        		;将原来的值再放回对应的寄存器
		RET    				;过程结束, 返回
	PRINTLN ENDP
	PRINT_ARRAY PROC		;打印输出排序的数字
		; 算法: 将一个数字逐一与10相除, 余数入栈, 商继续除以10, 直到商为0, 此时将栈中的元素逐一出栈, 则可以得到这个数字每一位的数, 再+48可以得到每一位的字符数字, 再输出即可看到这个数字被打印出来了
		; 因为直接输出这个数, 会输出这个数的ASCII码, 不是我们想要的值, 所以要注意分解位数, 再+48输出
	    PUSH AX
        PUSH BX
        PUSH CX
        PUSH DX
        MOV DI, OFFSET ARRAY_SIZE	;获取内存中这组数字的第一个数的偏移地址
        MOV CX, [DI]				;将偏移地址放入CX寄存器
        MOV SI, OFFSET NUMBER_ARRAY	;获取内存中存放这组数字长度的位置的偏移地址
        MOV BX, 0
        AGAIN:
            MOV AX, [BX+SI]			;将第一个数字的值放入AX中, 采用基址间址寻址
            PUSH CX					;下面要用到CX寄存器, 先将之前的内容入栈, 用完后再出栈即可恢复原来的功能
            PUSH BX					;下面要用到BX寄存器
            XOR CX, CX				;CX置零
            DIVISION:
                IDIV [TEN] 
                XOR BX, BX
                MOV BL, AH
                ADD BL, 48
                PUSH BX   
                MOV AH, 0   
                INC CX
                CMP AX, 0  
            JNE DIVISION
            OUTPUT:
                XOR AX, AX
                POP AX
                MOV DX, AX   
                MOV AH, 2
                INT 21H
            LOOP OUTPUT
            MOV DL, ' '
            INT 21H 
            POP BX
            ADD BX, 2
            POP CX     
        LOOP AGAIN
        POP DX
        POP CX
        POP BX
        POP AX
        RET
	PRINT_ARRAY ENDP
	
	ASSUME CS:CODE, ES:EXTRA, DS:DATA        
	START:            
		CALL INITIIALIZE
		CALL PRINT_ARRAY
		
	    MOV SI, OFFSET ARRAY_SIZE
	    SUB [SI], 1  
	    MOV AX, 0           ;AX记录外循环次数
	    I:                       
	        XOR DX, DX
	        MOV DX, [SI]
	        DEC DX
	        SUB DX, AX            
	        MOV BX, DX      ;BX记录内循环总次数
	        MOV CX, 0       ;CX记录内循环次数
	        XOR DX, DX
	        J: 	
	           CMP CX, BX
	           JE ENDJ
	           PUSH BX
	           ;BX = CX * 2
	           MOV BX, CX
	           SAL BX, 1
	           MOV SI, OFFSET NUMBER_ARRAY
	           MOV DX, [BX+SI]
	           MOV SI, OFFSET PRIVIOUS
	           MOV [SI], DX             
	           ;BX = BX + 2
	           ADD BX, 2
	           MOV SI, OFFSET NUMBER_ARRAY
	           MOV DX, [BX+SI]
	           MOV SI, OFFSET LAST 
	           MOV [SI], DX
	           
	           
	           CMP [PRIVIOUS], DX
	           ;> 后
	           JB SWPA
	                SUB BX, 2
	                MOV SI, OFFSET NUMBER_ARRAY 
	                XCHG [BX+SI], DX
	                ADD BX, 2
	                MOV SI, OFFSET NUMBER_ARRAY
	                MOV [BX+SI], DX
	           SWPA:
	           POP BX 
	           INC CX 
	           MOV SI, OFFSET ARRAY_SIZE
	           CMP CX, BX
	        JMP J
	        ENDJ:
	        INC AX

	        CMP AX, [SI]
	    JNE I
	    MOV SI, OFFSET ARRAY_SIZE
	    ADD [SI], 1    
	    CALL PRINTLN
	    CALL PRINT_ARRAY          
		CALL TERMINATE
CODE ENDS              
    END START
2. 从键盘输入一个字符串,并输出该字符串
DATA SEGMENT WORD PUBLIC 'DATA'       
	ORG 00H    
	STRING_BUFFER DB 50, 0, 50 DUP (00h)    ;字符串缓冲区
DATA ENDS
EXTRA SEGMENT WORD PUBLIC 'EXTRA'
EXTRA ENDS
CODE SEGMENT WORD PUBLIC 'CODE'    
	INITIIALIZE PROC    	;用来初始化段寄存器的过程    
		MOV AX, EXTRA          
		MOV ES, AX              
		MOV AX, DATA        
		MOV DS, AX        
		RET    
	INITIIALIZE ENDP    
	TERMINATE PROC        	;用来退出程序的过程
		MOV AH, 4CH        
		INT 21H          	;因为程序直接退出, 可以不需要加RET
	RET    
	TERMINATE ENDP      
	PRINTLN PROC        	;换行的过程
		PUSH AX        		
		PUSH DX        		;过程中要用到这两个寄存器, 先把原来的值存到栈里
		MOV AH, 2        	;功能号2是字符显示
		MOV DL, 0DH        	;DL寄存器存放打印字符, 这里是0D是换行的意思
		INT 21H        		;中断操作, 进行打印字符
		MOV DL, 0AH        	;0A是光标指向第一个字符的意思
		INT 21H        		;中断操作
		POP DX        	
		POP AX        		;将原来的值再放回对应的寄存器
		RET    				;过程结束, 返回
	PRINTLN ENDP      
	INPUT_STRING MACRO STRING_BUFFER_ADDRESS	;字符串输入过程   
		PUSH DX        					 
		PUSH AX               			 
		MOV DX, OFFSET STRING_BUFFER_ADDRESS	;字符串缓冲区的偏移地址放到DX寄存器    
		MOV AH, 0AH      				 ;功能号是0AH表示字符串输入  
		INT 21H        					 ;中断操作, 输入字符串
		CALL PRINTLN        			 ;输入结束, 调用换行过程
		POP AX        				
		POP DX      		
	ENDM    
	OUTPUT_STRING MACRO STRING_BUFFER	 ;字符串输出过程        
		PUSH CX        	
		PUSH BX               
		PUSH DX        
		PUSH AX        
		XOR CX, CX                  	 ;清空CX值
		MOV BX, OFFSET STRING_BUFFER     ;获取字符串缓冲区首地址   
		MOV CL, BYTE PTR [BX+1]          ;获取字符串长度, 存入CL  
		ADD BX, 2        			 	 ;BX = BX + 2
		ADD BL, CL             			 ;BL = BL + 2
		MOV BYTE PTR[BX], 0DH            ;将换行符存入偏移地址为BX内容的内存
		INC BX         					 ;BX = BX + 1
		MOV BYTE PTR[BX], 0AH            ;将0AH符存入偏移地址为BX内容的内存     
		INC BX        
		MOV BYTE PTR[BX], '$'      		 ;结尾放入$  
		MOV DX, OFFSET STRING_BUFFER     ;将字符串缓冲区地址放入DX
		ADD DX, 2        				 ;DX指向输入内容的第一个位置
		MOV AH, 09H        				 ;DOS软中断, 09H表示字符串显示
		INT 21H        					 ;中断
		POP AX        
		POP DX        
		POP BX        
		POP CX      
	ENDM    
	ASSUME CS:CODE, ES:EXTRA, DS:DATA        
	START:            
		CALL INITIIALIZE    			 ;调用初始化过程  
		STRING_BUFFER_ADDRESS = STRING_BUFFER	;获取内容地址               
		INPUT_STRING STRING_BUFFER_ADDRESS	;输入字符串          	             
		OUTPUT_STRING STRING_BUFFER      ;显示字符串              
		CALL TERMINATE
CODE ENDS        
	END START

结果
在这里插入图片描述

3. 从键盘输入一个2个数字, 将它转变为一个十位数, 并再转换为字符, 输出
DATA SEGMENT WORD PUBLIC 'DATA'       
	ORG 00H    
    TEN DB 10D
    SUM DB 00H
DATA ENDS
STACK SEGMENT WORD PUBLIC 'STACK'
STACK ENDS
CODE SEGMENT WORD PUBLIC 'CODE'    
	INITIIALIZE PROC    	;用来初始化段寄存器的过程    
		MOV AX, STACK          
		MOV SS, AX              
		MOV AX, DATA        
		MOV DS, AX        
		RET    
	INITIIALIZE ENDP    
	TERMINATE PROC        	;用来退出程序的过程
		MOV AH, 4CH        
		INT 21H          	;因为程序直接退出, 可以不需要加RET
	RET    
	TERMINATE ENDP      
	PRINTLN PROC        	;换行的过程
		PUSH AX        		
		PUSH DX        		;过程中要用到这两个寄存器, 先把原来的值存到栈里
		MOV AH, 2        	;功能号2是字符显示
		MOV DL, 0DH        	;DL寄存器存放打印字符, 这里是0D是换行的意思
		INT 21H        		;中断操作, 进行打印字符
		MOV DL, 0AH        	;0A是光标指向第一个字符的意思
		INT 21H        		;中断操作
		POP DX        	
		POP AX        		;将原来的值再放回对应的寄存器
		RET    				;过程结束, 返回
	PRINTLN ENDP 
   
    NUMBER_OUTPUT MACRO NUMBER_ADDRESS
        PUSH AX
        PUSH BX
        PUSH CX
        PUSH DX
        MOV AX, [NUMBER_ADDRESS]
        XOR CX, CX
        DIVISION:
            IDIV [TEN] 
            XOR BX, BX
            MOV BL, AH
            ADD BL, 48
            PUSH BX   
            MOV AH, 0   
            INC CX
            CMP AX, 0  
            JNE DIVISION
        OUTPUT:
            XOR AX, AX
            POP AX
            MOV DX, AX   
            MOV AH, 2
            INT 21H
            LOOP OUTPUT
        POP DX
        POP CX
        POP BX
        POP AX
    ENDM
                   
    ASSUME CS:CODE, SS:STACK, DS:DATA        
	START:            
		CALL INITIIALIZE
		;输入数字字符转变为数值存入栈            	
        XOR CX, CX
        XOR DX, DX
        MOV CX, 0
        CMP CX, 1   ;ZF = 0
    AGAIN:      ;输入    
        MOV AH, 1
        INT 21H
        SUB AL, 48   
        MOV AH, 0
        PUSH AX
        INC CX
        CMP CX, 2	;输入字符的个数, 2表示输入两字符
        JNE AGAIN
        ;将栈中的数值整体变成一个数值
        MOV DX, CX
        XOR BX, BX
        XOR CX, CX
    A:
        POP AX
        MOV BX, CX
        XOR CX, CX
        CMP CX, 0
        B:              
            CMP CX, BX
            JE DOWN   ;CX == BX
            MUL [TEN]
            INC CX
        JMP B
        DOWN:
            PUSH BX
            MOV BX, OFFSET SUM
            ADD [BX], AX
            POP BX
            INC CX       
            CMP CX, DX
        JE SHUT ;CX == DX
    JMP A
        SHUT:            
            CALL PRINTLN
            LEA SI, SUM   
            ;将数值转变为数字字符并输出
            NUMBER_OUTPUT SI
        CALL TERMINATE
CODE ENDS        
	END START

结果
在这里插入图片描述

4. 从键盘输入5个十以内的数(不包括10),求和并输出
DATA SEGMENT WORD PUBLIC 'DATA'       
	ORG 00H    
    TEN DB 10D
    SUM DB 00H
DATA ENDS
STACK SEGMENT WORD PUBLIC 'STACK'
STACK ENDS
CODE SEGMENT WORD PUBLIC 'CODE'    
	INITIIALIZE PROC    	;用来初始化段寄存器的过程    
		MOV AX, STACK          
		MOV SS, AX              
		MOV AX, DATA        
		MOV DS, AX        
		RET    
	INITIIALIZE ENDP    
	TERMINATE PROC        	;用来退出程序的过程
		MOV AH, 4CH        
		INT 21H          	;因为程序直接退出, 可以不需要加RET
	RET    
	TERMINATE ENDP      
	PRINTLN PROC        	;换行的过程
		PUSH AX        		
		PUSH DX        		;过程中要用到这两个寄存器, 先把原来的值存到栈里
		MOV AH, 2        	;功能号2是字符显示
		MOV DL, 0DH        	;DL寄存器存放打印字符, 这里是0D是换行的意思
		INT 21H        		;中断操作, 进行打印字符
		MOV DL, 0AH        	;0A是光标指向第一个字符的意思
		INT 21H        		;中断操作
		POP DX        	
		POP AX        		;将原来的值再放回对应的寄存器
		RET    				;过程结束, 返回
	PRINTLN ENDP 

    NUMBER_OUTPUT MACRO NUMBER_ADDRESS
        PUSH AX
        PUSH BX
        PUSH CX
        PUSH DX
        MOV AX, [NUMBER_ADDRESS]
        XOR CX, CX
        DIVISION:
            IDIV [TEN] 
            XOR BX, BX
            MOV BL, AH
            ADD BL, 48
            PUSH BX   
            MOV AH, 0   
            INC CX
            CMP AX, 0  
            JNE DIVISION
        OUTPUT:
            XOR AX, AX
            POP AX
            MOV DX, AX   
            MOV AH, 2
            INT 21H
            LOOP OUTPUT
        POP DX
        POP CX
        POP BX
        POP AX
    ENDM
                   
    ASSUME CS:CODE, SS:STACK, DS:DATA        
	START:            
		CALL INITIIALIZE
		;输入数字字符转变为数值存入栈            	
        XOR CX, CX
        XOR DX, DX
        MOV CX, 0
        CMP CX, 1   ;ZF = 0
    AGAIN:      ;输入    
        MOV AH, 1
        INT 21H
        SUB AL, 48   
        MOV AH, 0
        PUSH AX
        INC CX
        CMP CX, 5
        JNE AGAIN
        ;将栈中的数值相加变成一个数值
        XOR AX, AX
        XOR DX, DX
        LEA SI, SUM
        ACC:
            POP DX
            ADD [SI], DX
            LOOP ACC      
        CALL PRINTLN   
        ;将数值转变为数字字符并输出
        NUMBER_OUTPUT SI
        CALL TERMINATE
CODE ENDS        
	END START

结果
在这里插入图片描述

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值