基于8086的汇编语言程序设计

例题一:排序

从BLOCK起有20个单字节的数,把它们按降序排列

;选择排序法:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾

DATAS SEGMENT
	ORG 0000H
    BLOCK   DB  4,5,-2,7,8,9,2,1,0AH,1BH,87H,23H,44H,33H,45H,28H,0DH,8EH,66H,22H
	COUNT=$-BLOCK ;为排列数字的数量,$为当前地址
DATAS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS
START:
    MOV AX,DATAS
    MOV DS,AX         ;DS初始化
    LEA	SI,BLOCK
	MOV	CX,COUNT
AGAIN:
	MOV	AL,[SI]
	MOV	DI,SI
	MOV	DX,CX
NEXT1:               ;小循环,找出一组数里最小的,放在最前面
	CMP		AL,[DI]
	JGE		NEXT     ;AL>=[DI]时转移
	XCHG	AL,[DI]
NEXT:
	INC		DI
	DEC		DX
	JNZ		NEXT1
	MOV		[SI],AL
	INC		SI	
	LOOP	AGAIN

    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

例题二:字符串比较

比较两个字符串是否相同,并输出结果

DATA	SEGMENT	 
	STRING1		DB  'hELLO!'  ;注意字符串要用DB定义
	COUNT1=$-STRING1  ;字符串长度,$为字符串长度
	STRING2		DB  'hEL1O!'
	COUNT2=$-STRING2  
	IM				DB	'MATCH$' ;字符串输出时要求用$作为结束符
	NM				DB	'NOT MATCH$'
DATA	ENDS
CODE	SEGMENT
	ASSUME CS:CODE,DS:DATA
START: 
	MOV	AX,DATA
	MOV	DS,AX	;DS初始化
	LEA		SI,STRING1  ;取字符串首地址
	LEA		DI,STRING2
	MOV	CX,COUNT1
	MOV	BX,COUNT2
	CMP	CX,BX
	JNZ		DISPNOTMATCH ;如果字符串长度不等,直接判定不等
NEXT:	
MOV	AL,[SI] 
	MOV	AH,[DI]
	CMP	AL,AH 
	JNZ		DISPNOTMATCH  ;如果字符串内容不同,则判定不等
	INC		SI
	INC		DI
	LOOP	NEXT
ISMATCH:	
	MOV	DX,OFFSET IM
	MOV	AH,9  ;DOS功能调用,输出字符串
	INT		21H
	JMP		EXIT
DISPNOTMATCH:
	MOV	DX,OFFSET NM
	MOV	AH,9   ;DOS功能调用,输出字符串
	INT		21H
EXIT:	
	MOV	AH,4CH ;DOS功能调用,结束程序
	INT 	21H
CODE		ENDS
		END 	START

例题三:进制转化

将AX中有符号二进制数转化为十进制数ASCII码字符串,DX和CX返回串的偏移地址和长度

DATAS SEGMENT
	ASCNUM DB ?
DATAS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS
START:
    MOV AX,DATAS
    MOV DS,AX

    MOV AX,7999H ;要转化的二进制数
	MOV		BX,0
	LEA		DI,ASCNUM ;把字符串首地址放入DI寄存器
	CMP		AX,0
	JNS		CHG	;AX为正数时转移
	NEG		AX	;求补
	MOV	BYTE PTR [DI],'-' ;加负号
	JMP		NEXT
CHG: 
	MOV	BYTE PTR [DI],'+'  ;加正号
NEXT:
	MOV	DX,0
	MOV	CX,10000
	DIV		CX	;万位数字在AX中,余数在DX中
	CMP		AL,0
	JZ		N1  ;万位为零,转向千位
	MOV	BX,5 ;五位
	OR		AL,30H ;把万位变成ASCII码
	INC		DI  ;DI加一,指向下一个地址
	MOV	[DI],AL	;存万位
N1:
	MOV	AX,DX;余数放回AX
	MOV	DX,0
	MOV	CX,1000
	DIV		CX
	CMP		BX,0 
	JNZ		N2  ;BX有值时跳转去存千位,说明是个5位数
	CMP		AL,0
	JZ		N3  ;千位为零时跳转,位数小于4位
	MOV	BX,4
N2:
	OR		AL,30H ;转化为ASCII码
	INC		DI
	MOV	[DI],AL	;存千位
	
N3:
	MOV	AX,DX
	MOV	CL,100
	DIV		CL
	CMP		BX,0
	JNZ		N4  ;BX有值的时候跳转去存百位
	CMP		AL,0
	JZ		N5  ;百位为零时跳转,位数小于4位
	MOV	BX,3
N4:
	OR		AL,30H
	INC		DI
	MOV	[DI],AL	;存百位
N5:
	MOV	AL,AH
	MOV	AH,0
	MOV	CL,10
	DIV		CL
	CMP		BX,0
	JNZ		N6
	CMP		AL,0
	JZ		N7
	MOV	BX,2
N6:
	OR		AL,30H
	INC		DI
	MOV	[DI],AL	;存十位
N7:
	OR		AH,30H
	INC		DI
	MOV	[DI],AH
	CMP		BX,0
	JNZ		SN
MOV	BX,1
SN:
	MOV	CX,BX	; 存数位长度
	INC		CX	;串长=数位+1位符号位
	LEA		DX,ASCNUM ;DOS功能打印字符串时需要DX寄存器
PRINT:
	INC DI
	MOV AL,'$'
	MOV [DI],AL
	MOV DX, OFFSET ASCNUM
	MOV AH,9
	INT 21H
	
    MOV AH,4CH ;DOS功能,结束程序
    INT 21H
CODES ENDS
    END START

例题四:选择结构

键盘输入10个同学成绩,编制一个程序统计60-69,70-79,80-89,90-99,100分人数,分别存放在S6,S7,S8,S9及S10单元中。

;键盘输入的成绩以逗号分割
;输入完毕按回车结束
DATAS	SEGMENT
	STRING   DB  40,?,40 DUP(?)
	CJ	DB	10 DUP(?)
	S6	DB	?
	S7	DB	?
	S8	DB	?
	S9	DB	?
	S10	DB	?
DATAS	ENDS
CODES	SEGMENT
	ASSUME CS:CODES,DS:DATAS
START: 
	MOV	AX,DATAS
	MOV	DS,AX ;DS初始化
	LEA		DX,STRING  ;把STRING首地址移入DX
	MOV	AH,10 ;DOS功能,字符串输入
	INT		21H
	LEA		DI,CJ
	LEA		SI,STRING+2
	MOV	BH,0
	MOV	AL,0
AGAIN:
	MOV		BL,[SI]
	CMP		BL,','
	JZ		NEXT
	CMP		BL,0DH
	JZ		NEXT  ;如果是换行或者逗号就跳转
	SUB		BL,30H ;把ACSII码转化为0-9
	MOV		CL,10
	MUL		CL
	ADD		AL,BL ;AL乘十加上BL
	INC		SI
	JMP		AGAIN
NEXT:
	MOV		[DI],AL  ;此时AL里是两位十进制数,放入DI指向的单元中
	INC		DI  ;DI指向的地址加一
	MOV		AL,0  ;AL清零
	INC		BH ;成绩的数量加一
	INC		SI  ;原串地址加一
	CMP		BL,0DH
	JNZ		AGAIN
TJ:	
	LEA		DI,CJ
TJ1:
	MOV	AL,[DI]
	CMP		AL,100
	JZ		ADDS10
	CMP		AL,90
	JAE		ADDS9
	CMP		AL,80
	JAE		ADDS8
	CMP		AL,70
	JAE		ADDS7
	CMP		AL,60
	JAE		ADDS6
ADDS10:
	INC		S10
	JMP	TJNEXT
ADDS9:
	INC		S9
	JMP	TJNEXT
ADDS8:
	INC		S8
	JMP	TJNEXT
ADDS7:
	INC	S7
	JMP	TJNEXT
ADDS6:
	INC	S6
TJNEXT:
	INC DI
	DEC	BH
	JNZ	TJ1 ;BH为零,即所有成绩比较完毕后,进入下一阶段
	
    
EXIT:
MOV	AH,4CH
INT 	21H
CODES ENDS
    END START

你可能感兴趣的:(基于8086的汇编语言程序设计)