汇编语言的分支程序设计:
例题1:比较三个无符号数的大小,按照从大到小的顺序排列
关键的语句是:无符号数,因此所用语句是JAE实现跳转:
此外比较两个操作数所用的是CMP,交换两个操作数的是XCHG
书上的代码:
代码1:这样写法比较占用寄存器,但是寄存器之间交换数值比较快
;程序名称:实现三个无符号数的由小到大的排序 DATAS SEGMENT BUFFER DB 87,234,123 DATAS ENDS CODES SEGMENT ASSUME CS:CODES,DS:DATAS START: MOV AX,DATAS MOV DS,AX MOV SI,OFFSET BUFFER;把buffer的 偏移量交给变址寄存器SI MOV AL,[SI] MOV BL,[SI+1] MOV CL,[SI+2] CMP AL,BL ;比较AL,和BL的大小 JAE NEXT1 ;如果AL>BL转移到next1 XCHG AL,BL;交换AL,和BL NEXT1: CMP AL,CL ;比较AL和CL的大小 JAE NEXT2 XCHG AL,CL NEXT2: CMP BL,CL JAE NEXT3 XCHG BL,CL NEXT3: MOV [SI],AL MOV [SI+1],BL MOV [SI+2],CL MOV AH,4CH INT 21H CODES ENDS END START
代码2:这样的写法只用了AL,但是寄存器与存储器操作数指教的操作比较慢
1 ;程序功能,实现三个数的大小排序 2 DATAS SEGMENT 3 BUFFER DB 87,234,123 4 DATAS ENDS 5 6 7 CODES SEGMENT 8 ASSUME CS:CODES,DS:DATAS 9 START: MOV AX,DATAS 10 MOV DS,AX 11 12 MOV SI,OFFSET BUFFER 13 MOV AL,[SI] 14 CMP AL,[SI+1] 15 JAE NEXT1 16 XCHG AL,[SI+1] 17 MOV [SI],AL 18 NEXT1: CMP AL,[SI+2] 19 JAE NEXT2 20 XCHG AL,[SI+2] 21 MOV [SI+1],AL 22 NEXT2: MOV AL,[SI+1] 23 CMP AL,[SI+2] 24 JAE NEXT3 25 XCHG AL,[SI+2] 26 MOV [SI+1],AL 27 NEXT3: MOV AH,4CH 28 INT 21H 29 CODES ENDS 30 END START
例题2:写一个实现一位十六进制的数转换为对应的ASCII码的程序
;程序功能,实现16进制数值转换成对应的ASCII码
;原理:但十六进制数值为0到9的时候,对应的ASCII=x+30H
; 当十六进制为10到15的时候,对应的ASCII = x+37H
这里关键的语句是 JA,大于9的话,转移
之后便是程序跳转指令:JMP,但标号很多的时候,可以用LAB1,LAB2,LAB3这种类型的标号
1 ;程序功能,实现16进制数值转换成对应的ASCII码 2 ;原理:但十六进制数值为0到9的时候,对应的ASCII=x+30H 3 ; 当十六进制为10到15的时候,对应的ASCII = x+37H 4 DATAS SEGMENT 5 XX DB 4 6 ASCII DB ? 7 DATAS ENDS 8 ; 9 10 CODE SEGMENT 11 ASSUME CS:CODE,DS:DATAS 12 MOV AX,DATAS 13 MOV DS,AX 14 15 START: MOV AL,XX 16 AND AL,0FH 17 CMP AL,9 18 JA LAB1 19 ADD AL,30H 20 JMP LAB2 21 LAB1: ADD AL,37H 22 LAB2: MOV ASCII,AL 23 MOV AH,4CH 24 INT 21H 25 CODE ENDS 26 END START
例题3:写一个程序实现ASCII转换成对应的十六进制
1 ;ASCII 转换为16进制数 2 DATA SEGMENT 3 XX DB ? 4 ASCII DB 'a' 5 DATA ENDS 6 ; 7 8 CODE SEGMENT 9 ASSUME CS:CODE,DS :DATA 10 START: MOV AX,DATA 11 MOV DS,AX 12 MOV AL,ASCII 13 CMP AL,0 14 LAB: JB LAB5 15 MOV AH,AL 16 SUB AH,'0' 17 CMP AL,'9' 18 JBE LAB6 19 CMP AL,'A' 20 JB LAB5 21 MOV AH,AL 22 SUB AH,'A' -10 23 CMP AL,'F' 24 JBE LAB6 25 CMP AL,'a' 26 JB LAB5 27 MOV AH,AL 28 SUB AH,'a' -10 29 CMP AL,'f' 30 JBE LAB6 31 ; 32 LAB5 : MOV AH,-1 33 LAB6: MOV XX,AH 34 MOV AH,4CH 35 INT 21H 36 CODE ENDS 37 END START
利用地址表实现多向分支
当要根据某个变量的值,进行多种不同的处理时,就会产生了多向分支,多向分支在高级语言中常常用switch实现,在汇编语言中是使用地址表实现的
DSEG SEGMENT
……………………
COMTAB DW COMA,COMB,COMC,COMD
DW COME,COMF,COMG,COMH
DSEG ENDS
……………………
计算如果地址表内的地址,之后调用路口地址表即可
之后跳转指令用这个 JMP COMTAB[BX]
循环程序设计:
例题1:用计数法控制循环
1 ;程序功能,说明根据计数法控制循环体 2 DSEG SEGMENT 3 SUM DW ? 4 DSEG ENDS 5 6 CSEG SEGMENT 7 ASSUME CS:CSEG 8 9 START: MOV AX,40H 10 MOV DS,AX 11 MOV SI,0 12 MOV CX,1024 13 XOR AX,AX 14 AGAIN: ADD AX,[SI] 15 INC SI 16 INC SI 17 LOOP AGAIN 18 ; 19 ASSUME DS:DSEG 20 MOV BX,DSEG 21 MOV DS,BX 22 MOV SUM,AX 23 MOV AH,4CH 24 INT 21H 25 CSEG ENDS 26 END START
本例程中所用的关键指令为LOOP,LOOP指令使用的方法是在初始化CX的初值,每次执行一次LOOP,CX寄存器会减一
此外,还用了SI这个源地址指针,因为定义的变量时字,所以SI在循环的时候,调用了两次INC,在得到校验和的时候,重新设置了
数据段寄存器,以便于保存校验和
例题2:不用乘法指令实行乘法运算
假设乘法时234*125,不用乘法指令,可以有移位和累加两种方法
方法一:累加,可以看成是125个234相加,因此循环的时候,循环次数是CX=125
1 ;程序功能,说明根据计数法控制循环体 2 DSEG SEGMENT 3 SUM DW ? 4 DSEG ENDS 5 6 CSEG SEGMENT 7 ASSUME CS:CSEG 8 9 START: MOV AX,40H 10 MOV DS,AX 11 MOV SI,0 12 MOV CX,1024 13 XOR AX,AX 14 AGAIN: ADD AX,[SI] 15 INC SI 16 INC SI 17 LOOP AGAIN 18 ; 19 ASSUME DS:DSEG 20 MOV BX,DSEG 21 MOV DS,BX 22 MOV SUM,AX 23 MOV AH,4CH 24 INT 21H 25 CSEG ENDS 26 END START
这里用的指令时XOR,自己和自己异或等于0,还有JCXZ这条指令,JCXZ表示但cx寄存器为0的时候跳转
例题3:把16位的二进制数转换为5位十进制数值,为了简单,设二进制数时无符号的,采用8421BCD码表示十进制数
1 ;程序功能,实现十六位二进制数转换为十进制数 2 DSEG SEGMENT 3 DATA DW 23456 4 BUFFER DB 5 DUP(0) 5 JM DW 10000,1000,100,10,1 6 DSEG ENDS 7 8 CSEG SEGMENT 9 ASSUME CS:CSEG,DS:DSEG 10 START:MOV AX,SEG DATA 11 MOV DS,AX 12 MOV DI,OFFSET JM 13 MOV SI,OFFSET BUFFER 14 MOV CX,5 15 MOV AX,DATA 16 XOR DX,DX 17 NEXT: MOV BX,[DI] 18 ADD DI,2 19 DIV BX 20 MOV [SI],AL 21 INC SI 22 MOV AX,DX 23 XOR DX,DX 24 LOOP NEXT 25 MOV AX,4C00H 26 INT 21H 27 CSEG ENDS 28 END START
这里用了两个比较重要的概念,因为是16位的数值,因此必须明白,在进行16位的除法运算时,商保存在AX中,余数保存在DX中
在进行8位的除法运算时,AL保存商,AH保存余数
SEG可以返回变量所在的段值,OFFSET返回变量的偏移值,因此经常可以看到 MOV DI,OFFSET JM等等
在进行除法运算时,DIV BX隐含的是AX/BX
例题4
把一个字符串中的大写字母改成小写字母的程序
1 ;程序功能,把字符串中的大写字母改成小写字母 2 DSEG SEGMENT 3 STRING DB 'HOW arR YOu I',0 4 DSEG ENDS 5 CSEG SEGMENT 6 ASSUME CS:CSEG,DS:DSEG 7 START: MOV AX,DSEG 8 MOV DS,AX 9 MOV SI,OFFSET STRING 10 AGAIN: MOV AL,[SI] 11 OR AL,AL 12 JZ OK 13 CMP AL,'A' 14 JB NEXT 15 CMP AL,'Z' 16 JA NEXT 17 OR AL,20H 18 MOV [SI],AL 19 NEXT: INC SI 20 JMP AGAIN 21 OK: MOV AX,4C00H 22 INT 21H 23 CSEG ENDS 24 END START
这里需要注意的是,在字符串后面添加了一个0,这里是用来判断字符串是否为结束完,用OR AL,AL来判断,因为自己和自己相或,得到的是本身,只有和0相或,才能得到0
因此用JZ来转移到OK,
此外
比较CMP AL,'A',如果小的话用的是JB转移,
判断CMP AL 'Z',如果大于的话JA转移,
经过上面的判断可以得出AL中是大写字母,因此用OR AL,20H,把大写字母转换为小写字母
如果上述条件不满足,则INC SI
例题5
;写一个程序判定从地址0040:0000H开始的2048个内存字节党员中是否有字节A
;如果有字符A,则把第一个(按地址由小到大为序)含此指定字符的存储单元的地址偏移
;送到000:03FEH党员中,如果没有,则把特征值送到0FFFFH送到上述指定单元
1 ;写一个程序判定从地址0040:0000H开始的2048个内存字节党员中是否有字节A 2 ;如果有字符A,则把第一个(按地址由小到大为序)含此指定字符的存储单元的地址偏移 3 ;送到000:03FEH党员中,如果没有,则把特征值送到0FFFFH送到上述指定单元 4 ; 5 SEGADDR = 40H 6 OFFADDR = 0 7 COUNT = 2048 8 KEYCHAR = 'A' 9 SEGRESU = 0 10 OFFRESU = 3FEH 11 ; 12 CSEG SEGMENT 13 ASSUME CS:CSEG 14 START:MOV AX,SEGADDR 15 MOV DS,AX 16 MOV SI,OFFADDR 17 MOV CX,COUNT 18 MOV AL,KEYCHAR 19 NEXT: CMP AL,[SI] 20 JZ OK 21 INC SI 22 LOOP NEXT 23 MOV SI,0FFFFH 24 OK: MOV AX,SEGRESU 25 MOV DS,AX 26 MOV BX,OFFRESU 27 MOV [BX],SI 28 MOV AH,4CH 29 INT 21H 30 CSEG ENDS 31 END START
代码分析:首先是等号的运用 = ,常量的定义,类似于define
在查找的时候,调用CMP AL,[SI],这个查找到的话,调用JZ类似于若相等,则跳转
例题6
;设缓冲区中有一组单字节有符号数,以0为结束标志,写一个程序实现如下功能
;把前面5个正数一次送到缓冲区PDATA中,把前面5个负数送到缓冲区MDATA中,
;如果正数或者负数不足,则用0补足
1 ;设缓冲区中有一组单字节有符号数,以0为结束标志,写一个程序实现如下功能 2 ;把前面5个正数一次送到缓冲区PDATA中,把前面5个负数送到缓冲区MDATA中, 3 ;如果正数或者负数不足,则用0补足 4 5 MAX_COUNT = 5 6 DSEG SEGMENT 7 DATA DB 3,-4,5,6,-7,8,-9,-10,-1,-32,-132,27,58,44,-12,0 8 PDATA DB MAX_COUNT DUP (?) 9 MDATA DB MAX_COUNT DUP (?) 10 DSEG ENDS 11 ; 12 CSEG SEGMENT 13 ASSUME CS:CSEG,DS:DSEG 14 START: MOV AX,DSEG 15 MOV DS,AX 16 MOV CX,MAX_COUNT 17 MOV SI,OFFSET PDATA 18 MOV DI,OFFSET MDATA 19 MOV AL,0 20 NEXT1: MOV [SI],AL 21 MOV [DI],AL 22 INC SI 23 INC DI 24 LOOP NEXT1 25 MOV BX,OFFSET DATA 26 XOR SI,SI 27 XOR DI,DI 28 NEXT2: MOV AL,[BX] 29 INC BX 30 CMP AL,0 31 JZ OVER 32 JG PLUS 33 CMP DI,MAX_COUNT 34 JAE CONT 35 MOV MDATA[DI],AL 36 INC DI 37 JMP SHORT CONT 38 PLUS: CMP SI,MAX_COUNT 39 JAE CONT 40 MOV PDATA[SI],AL 41 INC SI 42 CONT: MOV AX,SI 43 ADD AX,DI 44 CMP AX,MAX_COUNT +MAX_COUNT 45 JB NEXT2 46 OVER: MOV AH,4CH 47 INT 21H 48 CSEG ENDS 49 END START
这个题目考了很多地方,当程序需要三个指针的时候,这个时候BX,SI,DI都可以作为指针
这个题目相当的给力,可以好好看看
版权所有:转载注明链接地址:http://www.cnblogs.com/fengdashen/p/3704148.html