工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 1427|回复: 1

汇编辅导--汇编语言常用子程序

[复制链接]
发表于 2003-9-7 10:42 | 显示全部楼层 |阅读模式
1、拆字与拼字:

【例1】将 GR0 中的四位 BCD 码从高到低依次存放到 GR2 所指的四个内存单元中。

START   
LEA GR3,4 ;循环计数器
L1 ST GR0,REG ;保护其余几位 BCD 码
AND GR0,C000F ;屏蔽高 3 位,留下最低 1 位 BCD 码
ST GR0,3,GR2 ;将此位 BCD 码存放到 GR2 所指第四个内存单元
LD GR0,REG ;恢复其余几位 BCD 码
SRL GR0,4 ;将已处理过的此位 BCD 码移出
LEA GR2.-1,GR2 ;地址指针减 1
LEA GR3,-1,GR3 ;循环计数器减 1
JNZ L1 ;未处理完,继续
RET   
C000F DC #000F  ;十六进制常数,屏蔽高 3 位 BCD 码用
REG DS 1  ;暂存单元  
END   

【例2】将存放在 GR2 所指的四个内存单元中的四位 BCD 码依从高到低顺序压缩到 GR0 中 。

START   
LEA GR0,0 ;GR0 清 0
LEA GR3,4 ;循环计数器
L1 SLL GR0,4 ;将已处理过的 BCD 码移到高位
LD GR1,0,GR2 ;GR1 用作临时工作寄存器
AND GR1,C000F ;屏蔽高 12 位
ST GR1,0,GR2 ;对内存单元中的 BCD 码预处理
ADD GR0,0,GR2 ;将已处理过的此位 BCD 码加到 GR0 低位
LEA GR2.1,GR2 ;地址指针指向下一位 BCD 码
LEA GR3,-1,GR3 ;循环计数器减 1
JNZ L1 ;未处理完,继续
RET   
C000F DC #000F  ;十六进制常数,屏蔽高 12 位二进制数
END   

2、数字与 ASCII 码之间的相互转换:

十进制数字 0~9 的 ASCII 码是 30H~39H ,所以只要将十进制数(BCD 码)加 30H 就是对应的 ASCII 码。

十六进制数转换成 ASCII 码可分成两段, 0~9 的 ASCII 码是 30H~39H ,即加 30H ;A~F 的ASCII 码是 41H~45H ,即加 37 H。

【例1】将 GR0 中的四位 BCD 码化成 ASCII 码从高到低依次存放到字符串变量 STR 中。

START   
LEA GR2,3 ;相对于 STR 首址的地址指针
LEA GR3,4 ;循环计数器
L1 ST GR0,REG ;保护其余几位 BCD 码
AND GR0,C000F ;屏蔽高 3 位,留下最低 1 位 BCD 码
ADD GR0,C30 ;转换成 ASCII 码
ST GR0,STR,GR2 ;将 ASCII 码存放到 GR2 所指第四个内存单元
LD GR0,REG ;恢复其余几位 BCD 码
SRL GR0,4 ;将已处理过的此位 BCD 码移出
LEA GR2.-1,GR2 ;地址指针减 1
LEA GR3,-1,GR3 ;循环计数器减 1
JNZ L1 ;未处理完,继续
RET   
C000F DC #000F  ;十六进制常数,屏蔽高 3 位 BCD 码用
C30 DC #30  ;十六进制常数 30  
STR DS 4   
REG DS 1  ;暂存单元  
END   

【例2】将 GR0 中的 16 位二进制数化成四位十六进制数 ASCII 码从高到低依次存放到字符串变量 STR 中。

START   
LEA GR2,3 ;相对于 STR 首址的地址指针
LEA GR3,4 ;循环计数器
L1 ST GR0,REG ;保护其余几位二进制数
AND GR0,C000F ;屏蔽高 12 位,留下最低 4 位二进制数
CPL GR0,C10 ;< 10 否?
JMI L2 ;< 10 跳过加 7 ,只加 30H
ADD GR0,C7 ;≥ 10,加 30H 前先加上 7
L2  ADD GR0,C30 ;加上 30H
ST GR0,STR,GR2 ;将 ASCII 码存放到 GR2 所指第四个内存单元
LD GR0,REG ;恢复其余几位二进制数
SRL GR0,4 ;将已处理过的此 4 位二进制数移出
LEA GR2.-1,GR2 ;地址指针减 1
LEA GR3,-1,GR3 ;循环计数器减 1
JNZ L1 ;未处理完,继续
RET   
C000F DC #000F  ;十六进制常数,屏蔽屏蔽高 12 位二进制数
C30 DC #30  ;十六进制常数 30  
C10 DC 10  ;十进制常数 10  
C7 DC 7  ;常数 7  
STR DS 4   
REG DS 1  ;暂存单元  
END   

【例3】将字符串 STR 中的四位十六进制数的 ASCII 码化成 16 位二进制数放到 GR0 中 。

START   
LEA GR0,0 ;GR0 清 0
LEA GR2,0 ;相对于 STR 首址的地址指针
LEA GR3,4 ;循环计数器
L1 SLL GR0,4 ;将已处理过的十六进制数移到高位
LD GR1,STR,GR2 ;GR1 用作临时工作寄存器
AND GR1,C00FF ;屏蔽高 8 位
SUB GR1,C30 ;减去30H
CPL GR1,C0A ;< 10 否?
JMI L2 ;< 10 ,完成转换
SUB GR1,C7 ;≥ 10,再减去 7
L2  ST GR1,STR,GR2 ;将 STR 中的 ASCII 码转换成十六进制数
ADD GR0,STR,GR2 ;将此位十六进制数加到 GR0 低位
LEA GR2.1,GR2 ;地址指针指向下一位 ASCII 码
LEA GR3,-1,GR3 ;循环计数器减 1
JNZ L1 ;未处理完,继续
RET   
C00FF DC #00FF  ;十六进制常数,屏蔽高 8 位用
C30 DC #30  ;十六进制常数 30  
C0A DC #0A  ;十六进制常数 0A  
C7 DC 7  ;常数 7  
STR DS 4   
END   

3、利用加减法及移位指令做乘法:

1)左移指令可将操作数乘 2 的整数次方(2、4、8、16);右移指令可将操作数除以 2 的整数次方。

若操作数是无符号数,用逻辑移位指令;若操作数是有符号数,用算术移位指令。

【例1】将 GR0 中的二进制数乘以 8。

SLL GR0,3

【例2】将 GR0 中的带符号二进制数除以 4。

SRA GR0,2

2)将移位指令和加减法结合起来可完成乘数不是 2 的整数次方的乘法运算。

【例1】将 GR0 中的二进制数乘以 10。

START  
SLL GR0,1
ST GR0,REG
SLL GR0,2
ADD GR0,REG
RET  
REG DS 1
END  

【例2】将 GR0 中的二进制数乘以 7。

START  
ST GR0,REG
SLL GR0,3
SUB GR0,REG
RET  
REG DS 1
END  

4、二进制数与十进制数的转换

1)二化十:

将二进制数转换为十进制数的一种常用算法是将被转换的二进制数依次被 10i( 对 16 位二进制数,i为 4、3、2、1、0)除,所得的商即为该十进制数位的值,其余数再被下一个 10i 除。一般用减法代替除法,即一边减 10i,一边计数器加 1,直到不够减再进行下一位 10i-1。以求得十进制数的各位数。

例如:一个相当于十进制数 34635 的二进制数,可先用 10000 去减,可减 3 次,得万位数是 3;再用 1000 去减,得千位数是 4;……

【例1】将 GR0 中的二进制数转换为十进制数的ASCII 码放入字符串 STR 中。

START   
LEA GR1,0 ;减数表及字符串指针  
LEA GR2,5 ;循环计数器  
L1  LEA GR3,48 ;该十进制位的数码预置 0 的 ASCII 码
L2 LEA GR3,1,GR3 ;数码位的 ASCII 码加 1
SUB GR0,SNO,GR1 ;操作数减去 10i   
JPZ L2 ;够减,继续  
ADD GR0,SNO,GR1 ;不够减,操作数及数码位的 ASCII 码恢复  
LEA GR3,-1,GR3  
ST GR3,STR,GR1 ;转换好的该位 ASCII 码存入结果字符串  
LEA GR1,1,GR1 ;地址指针加 1  
LEA GR2,-1,GR2 ;循环计数器减 1  
JNZ L1 ;未结束,继续下一位  
RET   
SNO DC 10000  
DC 1000  
DC 100  
DC 10  
DC 1  
STR DS 5  ;转换结果字符串
END   

1)十化二:

将十进制数转换为二进制数的算法基础是下面公式:

N = (Dn-1*10n-1+Dn-2*10n-2+……+D1*101+D0*100

  = ((…((Dn-1*10+Dn-2)*10+……+D1)*10+D0)*10

可以用循环程序实现此公式,*10 可用移位及加法指令完成。

【例2】将存放在字符串 STR 中的五位十进制数(<65536)的 ASCII 码转换成二进制数放到 GR0 中 。

START   
LEA GR0,0 ;转换结果寄存器清 0  
LEA GR2,5 ;循环计数器  
LEA GR1,0 ;地址指针(偏移量)
L1  SLL GR0,1 ;转换结果*10,先乘以 2
ST GR0,REG ;暂存 2*X
SLL GR0,2 ;2*X*4=8*X
ADD GR0,REG ;8*X + 2*X
LD GR3,STR,GR1 ;取一位 ASCII 码
AND GR3,C000F ;将 ASCII 码变成 BCD 码
ST GR3,REG ;结果暂存  
ADD GR0,REG ;将新的一位 BCD 码加到转换结果中  
LEA GR1,1,GR1 ;地址指针加 1  
LEA GR2,-1,GR2 ;循环计数器减 1  
JNZ L1 ;未结束,继续下一位  
RET   
C000F DC #000F  ;十六进制常数,屏蔽高 12 位二进制数
STR DC '35475'   
REG DS 1 ;暂存单元  
END   

5、求累加和

【例1】将变量 NUMBER 中的 5 个二进制数累加后放入变量 SUM 中。

START   
LEA GR2,NUMBER ;地址指针
LEA GR3,5 ;循环计数器
LEA GR0,0 ;累加和清0
L1 ADD GR0,0,GR2 ;累加
LEA GR2,1,GR2 ;地址指针指向下一个二进制数
LEA GR3,-1,GR3 ;计数器减1
JNZ L1 ;未完,继续
ST GR0,SUM ;累加结束,累加和送入 SUM 单元
RET   
NUMBER DS 5  
SUM DS 1  
END   

【例2】将自然数1~16累加后放入变量 SUM 中。

START   
LEA GR1,0 ;地址指针
LEA GR0,0 ;累加和清 0
L1 LEA  GR1,1,GR1 ;自然数加1
ST GR1,SUM ;加数(自然数)送入内存暂存
ADD GR0,SUM ;累加
CPA GR1,A  
JNZ L1 ;未完,继续
ST GR0,SUM ;累加结束,累加和送入 SUM 单元
EXIT   
A DC 16  
SUM DS 1  
END   

LEA GR1,0
LEA GR0,0 ;累加和(被加数)
CF LEA GR1,1,GR1
;
ADD GR0,C

JNZ CF
ST GR0,B
EXIT
A DC 16


6、利用递归方法求5的阶乘

START  ;主程序
LEA GR1,5 ;入口参数5(阶乘)→GR1  
CALL FACT ;调用FACT子程序  
EXIT   
FACT  LEA GR1,0,GR1  
JNZ IIA ;GR1未到0,继续递归
LEA GR1,1 ;GR1=0,退出递归
RET   
IIA  PUSH 0,GR1 ;保护这一级乘数
LEA GR1,-1,GR1 ;乘数减1  
CALL FACT ;继续调用FACT子程序自己  
POP GR1 ;逐级退出递归,恢复本级乘数  
LEA GR0,0  
CALL MUL  ;乘上本级乘数  
RET   
MUL ADD GR0,RESUL  
LEA GR1,-1,GR1  
JNZ MUL  
ST GR0,RESUL  
RET   
RESUL DC 1  
END  
发表于 2003-10-28 02:26 | 显示全部楼层
不懂ing!!!!!!!!!!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2024-5-30 13:41

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表