汇编语言实现简单的冒泡排序

        最近在学汇编,为逆向打基础,顺手写了一个汇编实现冒泡排序的小程序,代码已做好注释,有兴趣的可以简单看看。

BUF1-BUF10与BUF关系图(BUF中的90 80 70 60......为示例数据)


ARRADSBUF与BUF1-BUF10关系图

;定义数据段,BUF1-BUF10存储分割后的字符串
;BUF定义输入字符串缓冲区大小为255
;REAl为实际输入的字符串数
;iptstr为输入字符串存储的位置
;ARRADSBUF为构造的数组位置,存储分割后的每个字符串对应的缓冲区首地址
;notice和notice2位屏幕打印的提示
DATA SEGMENT
	BUF1 db 16 dup(?)
	BUF2 db 16 dup(?)
	BUF3 db 16 dup(?)
	BUF4 db 16 dup(?)
	BUF5 db 16 dup(?)
	BUF6 db 16 dup(?)
	BUF7 db 16 dup(?)
	BUF8 db 16 dup(?)
	BUF9 db 16 dup(?)
	BUF10 db 16 dup(?)
	BUF db 255
	REAL db ?
	iptstr db 255 dup(?)
	ARRADSBUF db 50 dup(?)
    notice db 'Please input 10 numbers:','$'
    notice2 db 'Sorted numbers:','$'
DATA ENDS
;定义堆栈段
SSTACK SEGMENT STACK
	   DW 64 DUP(?)
SSTACK ENDS
;定义代码段
CODE SEGMENT
;关联CS,DS寄存器和代码段,数据段
	ASSUME CS:CODE,DS:DATA
START:     ;将数据段段地址赋值到DS
			MOV AX,DATA
	       MOV DS,AX
		   ;获得notice偏移地址存入DX,利用中断09H打印字符串
           MOV DX,OFFSET notice
           MOV AH,09H
           INT 21H
		   ;换行
           MOV AH,02H
           MOV DL,0DH
           INT 21H
           MOV AH,02H
           MOV DL,0AH
           INT 21H
		   ;将输入缓冲区首地址存到DX,使用中断0AH获取输入并存入BUF中
		   LEA DX,BUF       
	       MOV AH,0AH
	       INT 21H
		   ;DX(输入缓冲区首地址)入栈,因为后面进行换行需要对DL赋值
           PUSH DX
		   ;换行
           MOV AH,02H
           MOV DL,0DH
           INT 21H
           MOV AH,02H
           MOV DL,0AH
           INT 21H
		   ;DX出栈
           POP DX
		;DX赋值给BX,BX加二(输入缓冲区第一位为缓冲区大小,第二位为实际输入字符个数,故输入缓冲区的首地址+2即为输入的字符串首地址)赋值给SI
		MOV BX,DX
		ADD BX,2H
	    MOV SI,BX
		;分别用将字符串分割缓冲区的首地址赋值给BX并且压栈
				LEA BX,BUF10
	    PUSH BX
				LEA BX,BUF9
	    PUSH BX
				LEA BX,BUF8
		PUSH BX
				LEA BX,BUF7
		PUSH BX
				LEA BX,BUF6
		PUSH BX
				LEA BX,BUF5
		PUSH BX
				LEA BX,BUF4
		PUSH BX
				LEA BX,BUF3
		PUSH BX
				LEA BX,BUF2
		PUSH BX
				LEA BX,BUF1
		PUSH BX
		;AH赋值00,后面用来作为缓冲区数目的计数器
	   MOV AH,00H
	   ;数组缓冲区首地址赋值给BX
	   LEA BX,ARRADSBUF
	   
A8:	   	;当AH等于0AH(十进制为10)时,转移A10
		CMP AH,0AH
		JE A10
		;将字符串分割缓冲区首地址退栈,赋值到DI,赋值DI到BP
		POP DI
		MOV BP,DI
		;字符串分割缓冲区首地址存入ARRADSBUF(数组缓冲区),偏移地址为16位,故之后BX+2
		MOV DS:WORD PTR [BX],DI
		ADD BX,2H
		;判断SI位置的字符是否为空格,是则转移A7
A6:		MOV DL,20H
		CMP DS:BYTE PTR[SI],DL
		JE A7
		;判断SI位置是否为标志键盘输入结束的0DH,是则转移A13
		MOV DL,0DH
		CMP DS:BYTE PTR[SI],DL
		JE A13
		;如以上判断皆不满足,将SI中偏移地址所对应字符按字节赋值到DL(一个ASCII字符占8位,即一个字节)
		MOV DL,DS:BYTE PTR[SI]
		;将DL赋值到DI中存储的偏移地址所对应的值(DI中存储的是当前操作的分割字符串缓冲区的首地址)
		MOV DS:BYTE PTR[DI],DL
		;SI和DI各自增1,指向输入的字符串缓冲区和分割字符串缓冲区的下一字符,转移A6
		INC SI
		INC DI
		JMP A6

;数组缓冲区首地址送AX,BX(写入字符串分割缓冲区首地址后的数组缓冲区末尾地址+1)送DI,BX与AX之差送AX,使用DIV进行除法运算,
;AX除以DL(02H)商送AL,送AL到CL,CX即为数组缓冲区中存在的地址数目(通俗的讲,CX代表了数组中元素的数量),立即数FFH送BL作为排序未完成标志,转移A1		
A10: LEA AX,ARRADSBUF
	MOV DI,BX
	SUB BX,AX
	MOV AX,BX
	MOV DL,02H
	DIV DL
	MOV CH,00H
	MOV CL,AL
	MOV BL,0FFH
	JMP A1

;字符串分割缓冲区写入分割后字符串后在其字符串末尾写入'$'表示字符串结束
A7:    MOV AL,24H
	   MOV DS:[DI],AL
;DI-BP,得到分割字符串缓冲区中字符串长度送DX,将DX写入字符串分割缓冲区尾部(定义的分割字符串缓冲区大小为16,则首地址+0FH得到末尾地址)
	   SUB DI,BP
	   MOV DX,DI
	   MOV DS:BYTE PTR[BP+0FH],DL
;SI自增1,作用是跳过空格
	   INC SI
;AH自增1,作用是表示当前字符串分割缓冲区已经写入完毕,后转移A8
	   INC AH
	   JMP A8
;字符串分割缓冲区写入分割后字符串后在其字符串末尾写入'$'表示字符串结束
A13:   MOV AL,24H
	   MOV DS:[DI],AL
;DI-BP,得到分割字符串缓冲区中字符串长度送DX,将DX写入字符串分割缓冲区尾部(定义的分割字符串缓冲区大小为16,则首地址+0FH得到末尾地址),转移A10
	   SUB DI,BP
	   MOV DX,DI
	   MOV DS:BYTE PTR[BP+0FH],DL
	   JMP A10

;判断未完成标志,如BL不为FFH,则转移A4	   
A1:	   CMP BL,0FFH
	   JNZ A4
;送00H到BL(置未完成标志为已完成,如交换元素位置行为发生,则BL会重新在后面的语句中被置FFH(未完成))
	   MOV BL,00H
;CX减一,表征当前冒泡排序剩余趟数,如结果为0,转移A4
	   SUB CX,1H
	   JZ A4
	   ;DI(写入字符串分割缓冲区首地址后的数组缓冲区末尾地址+1),CX分别压栈
	   PUSH DI
	   PUSH CX
;DI-2,得到写入字符串分割缓冲区首地址后的数组缓冲区中最后一个地址(DI只需在循环中不断减2即可得到数组中每一个字符串分割缓冲区地址)
A2:    SUB DI,0002H
;按字取DI所对应的值(字符串分割缓冲区首地址)送BP
	   MOV BP,WORD PTR[DI]
;由于BP为字符串分割缓冲区首地址,再按字节取其对应的值得到字符串分割缓冲区中数字最高位数字ASCII码送AH
	   MOV AH,DS:BYTE PTR [BP]
;字符串分割缓冲区最后一位(存储的字符串分割缓冲区中字符串长度)送DH
	   MOV DH,DS:BYTE PTR[BP+0FH]
;DI(数组中地址指针)-2,指向前一个字符串分割缓冲区地址
	   SUB DI,0002H
;按字取DI对应的值(前一字符串分割缓冲区地址)送SI
	   MOV SI,WORD PTR[DI]
;按字节取SI对应的值送AL,(此时AL中为前一字符串分割缓冲区中数字最高位数字ASCII码)
	   MOV AL,DS:BYTE PTR [SI]
;前一字符串分割缓冲区最后一位(存储的前一字符串分割缓冲区中字符串长度)送DL
	   MOV DL,DS:BYTE PTR[SI+0FH]
;比较两个分割字符串缓冲区中字符串的长度(数字位数),后大于前转移A3
	   CMP DH,DL
	   JA A3
;比较两个分割字符串缓冲区中字符串的长度(数字位数),后小于前转移A5
	   CMP DH,DL
	   JB A5
;比较两个分割字符串缓冲区最高位数字ASCII码,后大于前转移A3
	   CMP AH,AL
	   JA A3
;比较两个分割字符串缓冲区最高位数字ASCII码,后小于前转移A5
	   CMP AH,AL
       JB A5
;处理相等的情况
;分别按字节取BP和SI在两个分割字符串缓冲区指向的数字
A11:	MOV AH,DS:BYTE PTR [BP]
		MOV AL,DS:BYTE PTR [SI]
;比较两数字ASCII码,同之前
		CMP AH,AL
		JA A3
		CMP AH,AL
		JB A5
;BP,SI自增1,指向两个分割字符串缓冲区次高位数字
		INC BP
		INC SI
;转移A11
		JMP A11

;交换两数字对应的字符串分割缓冲区在数组缓冲区中的位置		
A5:   	PUSH WORD PTR[DI+2H]
		PUSH WORD PTR[DI]
		POP WORD PTR[DI+2H]
		POP WORD PTR[DI]
;排序未完成标志
	   MOV BL,0FFH
;数组缓冲区中地址指针+2,循环A2,继续比较(LOOP时每执行一次A2,CX减1)
A3:    ADD DI,2H
	   LOOP A2
;CX和DI退栈,转移A1
	   POP CX
	   POP DI
	   JMP A1

;送notice2偏移地址到DX并用中断显示	   
A4:        MOV DX,OFFSET notice2
           MOV AH,09H
           INT 21H
;换行
           MOV AH,02H
           MOV DL,0DH
           INT 21H
           MOV AH,02H
           MOV DL,0AH
           INT 21H
;数组首地址送BX
		   LEA BX,ARRADSBUF
;按字取数组中存储的排序后的分割字符串缓冲区地址,并调用09H中断打印分割字符串缓冲区中的字符串
A12:	   MOV DX,DS:WORD PTR[BX]
           MOV AH,09H
           INT 21H
;打印完每个字符串后都打印空格
		   MOV DL,20H
		   MOV AH,02H
		   INT 21H
;数组中的地址指针加2
		   ADD BX,2H
;比较DI(数组中元素(地址)的末尾地址+1)是否等于BX,不等转移A12
		   CMP DI,BX			
		   JNE A12
;程序结束
           MOV AX,4C00H
           INT 21H
CODE ENDS
END START


  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值