汇编语言程序设计典型案例
一、顺序程序设计
例:从键盘输入两个数字(0-9)输出它们积。
CODE SEGMENT
ASSUME CS:CODE
ORG 100H
Main:MOV AH,1
INT 21H
MOV BL,AL
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,1
INT 21H
SUB AL,30H
SUB BL,30H
MUL BL
MOV BL,10
DIV BL
ADD AX,3030H
MOV BX,AX
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV DL,BL
MOV AH,2
INT 21H
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV DL,BH
MOV AH,2
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END Main
二、分支程序
1 简单分支
例:已知AX中放有一个16位无符号数,BL中放有一个8位无符号数,编写将它们相加结果放DX的程序。
2 两路分支
例:编写将BX与DX中较大的一个无符号数放入AX中的程序。( X2 已验证)
DATA SEGMENT
BUF1 DW ?,?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
LEA SI,BUF1
MOV BX,[SI]
INC SI
MOV DX,[SI]
CMP BX,DX
JA Lab1
MOV AX,DX
JMP Lab2
Lab1:MOV AX,BX
Lab2:MOV AH,4CH
INT 21H
CODE ENDS
END START
3 复杂条件的分支
例子:从键盘读入两个一位数,并输出其积。P52(X1 已验证)
CODE SEGMENT
ASSUME CS:CODE
ORG 100H
MOV AH,1;从键盘读第一个数
INT 21H
CMP AL,’0′
JB Lab1
CMP AL,’9′
JA Lab1
MOV BL,AL
MOV AH,2
MOV DL,13H
INT 21H
MOV DL,10H
INT 21H
MOV AH,1; 从键盘读第二个数
INT 21H
CMP AL,’0′
JB Lab1
CMP AL,’9′
JA Lab1
SUB AL,30H ;把后读入的数的ASCALL码还原为数字
SUB BL,30H ;把先读入的数的ASCALL码还原为数字
MUL BL ;两数相
MOV BL,10 ;
DIV BL ;分拆积的十位和个位
ADD AX,3030H ;积转换为ASCALL码
MOV BX,AX
MOV AH,2
MOV DL,13H ;回车
INT 21H
MOV DL,10H ;换行
INT 21H
MOV DL,BL;输出显示十位
MOV AH,2
INT 21H
MOV DL,BH;输出显示个位
INT 21H
JMP Lab2
Lab1:MOV AH,2
MOV DL,’E’
INT 21H
Lab2:MOV AH,4CH
INT 21H
CODE ENDS
END
4 多路分支
例3 从键盘上接收按键输入,如果按下的是小写字母则输出‘L’,是大写字母则输出‘U’,如果是数字则输出‘N‘,都不是则输出‘*’。
CODE SEGMENT
ASSUME CS:CODE
ORG 100H
START:MOV AH,1
INT 21H
CMP AL,’0′
JB
Lab1
CMP AL,’9′
JA Lab2
MOV DL,’N’
JMP Lab3
Lab2:CMP AL,’A’
JB Lab1
CMP AL,’Z’
JA Lab4
MOV DL,’U’
JMP Lab3
Lab4:CMP AL,’a’
JB Lab1
CMP AL,’z’
JA Lab1
MOV DL,’L’
JMP Lab3
Lab1:MOV DL,’*’
Lab3:MOV AH,2
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
例4:符号函数
1 当X>0
Y= 0 当X=0
-1 当X<0
假定任意给定的X值存放在XX单元,函数Y的值存放在YY单元。编程表示该符号函数。
DATA SEGMENT 2P130
XX DB X
YY DB ?
DATA ENDS
CODE SELTGMENT
ASSUME CS:CODE,DS:DATA
MOV AX,DATA
MOV DS,AX
MOV AL,XX
CMP AL,0
JGE BIGPR
MOV YY,0FFH
BIGPR:JE EQUPR
MOV YY,1
HLT
EQUPR:MOV YY,0
HLT
CODE ENDS
END
三、循环程序设计
1 先判断再循环
例1:设DS:SI中存放了一个字符串的首地址,字符串以“$”结束,编写程序把该字符串显示在
屏幕上(结束符“$”不显示)。1P56 (X4 已验证)
DATA SEGMENT
BUF DB ‘123456789$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
ORG 100H
START:MOV AX,DATA
MOV DS,AX
LEA SI,BUF
Lab1:CMP BYTE PTR [SI],’$’
JE Lab2
MOV AH,02H
MOV DL,[SI]
INT 21H
INC SI
JMP Lab1
Lab2:MOV AH,4CH
INT 21H
CODE ENDS
END START
2 先循环再判断
例2:设DS:SI中存放了一个字符串的首地址,字符串以“$”结束,编写程序把
该字符串包括结束符’$’显示在屏幕上。P56 (X5 已验证)
DATA SEGMENT
BUF DB ‘123456789$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
ORG 100H
START:MOV AX,DATA
MOV DS,AX
LEA SI,BUF
Lab1:MOV AH,02H
MOV DL,[SI]
INT 21H
INC SI
CMP DL,’$’
JNE Lab1
MOV AH,4CH
INT 21H
CODE ENDS
END START
3 计数型循环
例4:编写在一行上依次显示屏26个大写英文字母的程序。P57(X6 已验证)
CODE SEGMENT
ASSUME CS:CODE
START:MOV CX,26
MOV DL,‘A’
Lab1:MOV AH,2
INT 21H
ADD DL,1
LOOP Lab1
MOV AX,4C00H
INT 21H
CODE ENDS
END START
4 用JCXZ指令的循环
例5:编写将0~9这10个自然数相加并显示其结果的程序。 (X7)(已验证)
CODE SEGMENT
ASSUME CS:CODE,DS:CODE
START:PUSH CS
POP DS
MOV AX,0
XOR BX,BX
MOV CX,11
LOP1:INC BX
SUB CX,1
JCXZ LOP2
ADD AX,BX
JMP LOP1
LOP2:MOV BL,10
DIV BL
ADD AX,3030H
MOV BX,AX
MOV DL,BL
MOV AH,2
INT 21H
MOV DL,BH
MOV AH,2
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
5 循环嵌套
例子:在屏幕上显示如下由数字组成的形状。 (X8 已验证)
0123456789
1234567890
2345678901
3456789012
4567890123
5678901234
6789012345
7890123456
8901234567
9012345678
源程序如下:
CODE SEGMENT
ASSUME CS:CODE
Main:MOV BL,0 ;显示10行的外循环计数
Lab1:MOV CX,10 ;每行10个数的内循环计数
MOV DL,’0′ ;每行第一个字符
ADD DL,BL
Lab2:MOV AH,02H ;显示单个字符
INT 21H
ADD DL,1
CMP DL,’9′
JBE Lab3
MOV DL,’0′; DL逐个递减取下一字符,超过‘9’则回‘0’
Lab3:LOOP Lab2 ;内循环控制
MOV DL,0DH ;回车
INT 21H
MOV DL,0AH
INT 21H
ADD BL,1
CMP BL,10 ;外循环控制
JB Lab1
MOV AH,4CH
INT 21
CODE ENDS
END Main
四、子程序设计
例1:见字符串处理的例子2
例2:要求编写一个子程序,这个子程序能自动将AX的数值以十进制的显示形式输出。(X9)
CODE SEGMENT
ASSUME CS:CODE
START:
MOV AX,1234
CALL PRI
mov dl,10;换行
mov ah,2
int 21h
mov dl,13;回车
mov ah,2
int 21h
MOV AX,56H
CALL PRI
mov ah,4ch
int 21h
pri proc near
push bx
push cx
push dx
mov bx,10;十进制
mov dx,0;被除数的高16位
mov cx,0;位数
rediv: div bx ;dxax / bx
push dx;余数
mov dx,0
inc cx
cmp ax,0
jnz rediv
mov ah,2
reout: pop dx
add dl,30h;将数值位
int 21h
loop reout
pop dx
pop cx
pop bx
ret
pri endp
code ends
end start
五、字符串处理程序
例1:将数据段BUF1单元开始的10个字节依次传送到附加段BUF2开始的内存区并回显。P119 (X10 已验证)
DATA SEGMENT
BUF1 DB 10 DUP(‘A’)
DATA ENDS
EXTR SEGMENT
BUF2 DB 10 DUP(?)
EXTR ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:EXTR
START:MOV AX,DATA
MOV DS,AX
MOV AX,EXTR
MOV ES,AX
LEA SI,BUF1
LEA DI,BUF2
MOV CX,10
CLD
REP MOVSB
MOV CX,10
LEA DI,BUF2
LOP1:MOV DL,[DI]
MOV AH,02H
INT 21H
INC DI
LOOP LOP1
MOV AH,4CH
INT 21H
CODE ENDS
END START
例2:设计一个口令设置程序,其功能要求如下:程序执行首先显示提示:Please input
the paassword:(请输入口令:);如果用户输入正确的口令USER(并回车),则输出
OK!WELCOME YOU;否则显示提示:Error!inpt again:(有错误,请重新输入);三次
口令不对就退出。P125 (X11 已验证)
DATA SEGMENT
PASSWORD DB ‘USER’
COUNT EQU $-PASSWORD
INPUT DB CO
UNT
STRING DB COUNT DUP(?)
PROMPT DB ‘Please input the password:$’
MSG1 DB ‘OK!WELCOME YOU $’,0DH,0AH
MSG2 DB ‘Error!input again:$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
LEA DX,PROMPT
MOV AH,09H
INT 21H
MOV BX,3
AGAIN:LEA DX,INPUT
MOV AH,0AH
INT 21H
LEA SI,PASSWORD
LEA DI,STRING
MOV CX,COUNT
CLD
REPE CMPSB
JNZ EXIT
CALL CRLF
LEA DX,MSG2
MOV AH,9H
INT 21H
DEC BX
JNZ AGAIN
JMP DONE
EXIT:CALL CRLF
LEA DX,MSG1
MOV AH,09H
INT 21H
DONE:MOV AH,4CH
INT 21H
CRLF PROC
MOV AH,02H
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
RET
CRLF ENDP
CODE ENDS
END START
例3 编写在屏幕上输出如下图形的程序。P81 (X12 已验证)
9
89
789
6789
56789
456789
3456789
23456789
123456789
源程序如下:(能汇编已验证结果)
DATA SEGMENT
BUF DB ‘123456789’,13,10,24H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
Main:MOV DX,DATA
MOV DS,DX
MOV CX,9
LEA DX,BUF+8; LEA DX,[BUF+8];同样可行,为什么?
MOV AH,09H
Lab:INT 21H
SUB DX,1
LOOP Lab
MOV AH,4CH
INT 21H
CODE ENDS
END Main
例4:采用09H号DOS中断功能调用输出显示指定的字符串。(已验证)(X13)
CODE SEGMENT
ASSUME CS:CODE,DS:CODE
ORG 100H
START:JMP BEGIN
STRING DB ‘Hello,How are you!’,’$’
BEGIN:MOV AX,CODE
MOV DS,AX
LEA DX,STRING
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START