;范例1
LSDAA: ADC R16,R16 ;十进制数(在R16中)左移调整子程序 ADDAA: IN R6,SREG ;bcd码相加调整子程序,先保存相加后的
LDI R17,$66 ;状态the old status
ADD R16,R17 ;再将和预加立即数$66
IN R17,SREG ;输入相加后新状态(the new status)
OR R6,R17 ;新旧状态相或
SBRS R6,0 ;相或后进位置位则跳行
SUBI R16,$60 ;否则减去$60(十位bcd不满足调整条件)
SBRS R6,5 ;半进位置位则跳行
SUBI R16,6 ;否则减去$06(个位bcd不满足调整条件)
RET
佳能960
;范例2
SUDAA: BRCC SBD1 ;bcd码减法调整子程序,差在R16中
BRHC SBD3
SUBI R16,$66 ;进位半进位都置位,将差减去立即数$66
SEC ;并恢复借位C
RET ;ret. with seC
SBD1: BRHC SBD2 ;进位半进位都清位,返回
SUBI R16,6 ;进位清除而半进位置位,将差减去6
SBD2: RET ;ret. with clC
SBD3: SUBI R16,$60 ;进位置位而半进位清除,将差减去$60
SEC ;并恢复借位C
RET ;ret. with seC
;范例3
RSDAA: SBRC R16,7 ;bcd码(在R16中)右移调整子程序
SUBI R16,$30 ;十位BCD最高位为1(代表8),将其变为5(否则跳行)
SBRC R16,3
SUBI R16,3 ;个位BCD最高位为1(代表8),将其变为5(否则跳行)
RET
;范例4
ADBCD4: MOV R16,R15 ;4字节压缩bcd码相加子程序
ADD R16,R11 ;R12,R13,R14,R15内为被加数,R8,R9,R10,R11内为加数
RCALL ADDAA ;相加后调整
MOV R15,R16 ;并返还调整后结果
MOV R16,R14
ADC R16,R10
RCALL ADDAA
MOV R14,R16
MOV R16,R13
ADC R16,R9
RCALL ADDAA
MOV R13,R16
MOV R16,R12
ADC R16,R8
RCALL ADDAA
MOV R12,R16
RET
;范例5
ADBCD: LDI R16,4 ;多字节压缩bcd码相加子程序
MOV R7,R16 ;(r7):字节数
CLC
ADLOP: LD R16,-X ;X-1指向被加数;
LD R6,-Y ;Y-1指向加数
ADC R16,R6
RCALL ADDAA ;相加后调整
ST X,R16 ;返还调整后结果
DEC R7
BRNE ADLOP
RET
;范例6
SUBCD4: MOV R16,R15 ;4字节压缩bcd码减法子程序
SUB R16,R11 ;R12,R13,R14,R15内为被减数,R8,R9,R10,R11内为减数
RCALL SUDAA ;相减后调整
MOV R15,R16 ;并返还调整后结果
MOV R16,R14
SBC R16,R10
RCALL SUDAA
MOV R14,r16
MOV R16,R13
SBC R16,R9
RCALL SUDAA
MOV R13,R16
MOV R16,R12
SBC R16,R8
RCALL SUDAA
MOV R12,R16
RET
;范例7
SUBCD: LDI R16,4 ;多字节压缩bcd码
相减子程序
MOV R7,R16 ;(r7):压缩bcd码字节数
CLC
SUBLP: LD R16,-X ;X-1指向被减数
LD R6,-Y ;Y-1指向减数
SBC R16,R6
RCALL SUDAA ;相减后调整
ST X,R16 ;返还调整后结果
DEC R7
BRNE SUBLP
RET
;范例8 ;16位被乘数*16位乘数-->32位积
MUL16: LDI R16,17 ;(r10r11)*(r14r15)-->r12r13r14r15
ClR R12
ClR R13 ;积的高位字预清除
CLC ;第1次只右移,不相加
MLOOP: BRCC MUL1 ;
ADD R13,R11 ;乘数右移移出位为1,将被乘数加入部分积
ADC R12,R10
MUL1: ROR R12
ROR R13
ROR R14
ROR R15 ;部分积连同乘数整体右移1位
DEC R16
BRNE MLOOP ;17次右移后结束
RET
;范例9 ;16位整数被乘数*16位小数乘数-->16位整数积,精确到0.5 MUL165: RCALL MUL16 ;先得到32位积
SBRS R14,7 ;积小数部分最高位为1,将整数部分加1
第一首七言诗
RET ;否则返回
LDI R17,255
SUB R13,R17只有一个地球教学实录
SBC R12,R17 ;以减去-1($FFFF)替代加1
RET
;范例10 ;32位被除数/16位除数-->16位商,精确到1
DIV16: LDI R16,16 ;(r12r13r14r15)/(r10r11)-->r14r15
DLOOP: LSL R15
ROL R14
ROL R13
ROL R12 ;被除数左移1位
BRCS DI1
SUB R13,R11
SBC R12,R10 ;移出位为0,被除数高位字减去除数试商
BRCC DI2 ;够减,本位商为1
ADD R13,R11
ADC R12,R10 ;否则恢复被除数
RJMP DI3 ;本位商0
DI1: SUB R13,R11
SBC R12,R10 ;移出位为1,被除数高位字减去除数
DI2: INC R15 ;本位商1
DI3: DEC R16
BRNE DLOOP
RET
;范例11 ;32位被除数/16位除数-->16位商,精确到0.5
;可能产生溢出!例$7FFFC000/$8000=$FFFF.8->$10000!
DIV165: RCALL DIV16 ;(r12r13r14r15)/(r10r11)-->r14r15
LSL R13
ROL R12 ;余数乘2
BRCS D165 ;有进位,转5入
SUB R13,R11
SBC R12,R10 ;否则,余数乘2减去除数
BRCS D164 ;不够减,转4舍
D165: CLR R13 ;否则将商增1
SEC
ADC R15,R13
ADC R14,R13
ADC R13,R13 ;若有溢出,溢出位在R13中
RET
D164: CLR R13
RET
;范例12 ;32位整数/16位整数->16整数+16位小数->4字节浮点数
;(r12r13r14r15)/(r10r11)-->r12r13r14r15
DIV16F: RCALL DIV16 ;先做整数除法
MOV R9,r15
MOV R8,r14 ;保存整数部分
CLR R15
CLR R14
RCALL DIV16 ;除得小数部分
MOV R11,R15
MOV R15,R14
MOV R13,R8
MOV R14,R9 ;整数部分在r13r14,小数部分在r15r11
LDI R17,$90 ;预
设阶码$90(整数为16位)
MOV R12,R17
LDI R17,32 ;设32次右移
DIV16L: SBRC R13,7
RJMP NMLDN ;最高位为1,已完成规格化
LSL R11 ;否则继续右移R13,R14,R15,R11
ROL R15
ROL R14
ROL R13
DEC R12 ;阶码减1
DEC R17
BRNE DIV16L
CLR R12 ;右移达32次,浮点数为零,置零阶
RET
NMLDN: SBRS R11,7
RJMP DIVRT ;欲舍去部分(R11)最高位为0,转4舍
RCALL INC3 ;否则尾数部分增1
BRNE DIVRT
INC R12 ;尾数增1后变为0,改为0.5,并将阶码增1
DIVRT: LDI R17,$7F ;将尾数最高位清除,表示正数(负数不要清除)
AND R13,R17 ;规格化浮点数在R12(阶码)R13R14R15(尾数)中
RET
;范例13 ;(R16,R12,R13,R14,R15)/(R10,R11)-->R13,R14,R15
DIV24: CLR R16 ;32位整数/16位整数->24位整数,要求(R10)不为0;否则
;要求(R12)<(R11)
DIV40: LDI 17,24 ;40位整数/16位整数->24位整数 要求(R16,R12)
LXP: LSL R15 ; <(R10,R11)
ROL R14
ROL R13
ROL R12
ROL R16
BRCC LXP1
SUB R12,R11 ;右移后C=1 够减
SBC R16,R10 ;被除数减去除数
RJMP DIV0 ;本位商为1
LXP1: SUB R12,R11 ;C=0
SBC R16,R10 ;被除数减去除数试商
BRCC DIV0 ;C=0 够减,本位商1
ADD R12,R11
ADC R16,R10 ;否则恢复被除数,本位商0
RJMP DIV1
DIV0: INC R15 ;记本位商1
DIV1: DEC R17
BRNE LXP
LSL R12
灰度图
ROL R16
BRCS GINC ;C=1,5入
SUB R12,R11
SBC R16,R10
BRCS RET3 ;不够减,舍掉
GINC: RCALL INC3 ;将商增1
RET3: RET
;范例14 ;定点整数(最大$FFFFFFFF)开平方子程序
INTSQR: LDI R16,17 ;SQR(R12,R13,R14,R15)-->(r15r8r9)
CLR R8 ;R8,R9存储平方根
CLR R9 ;r10,r11,r12,r13,r14,r15
CLR R10 ; r8, r9(根) r16 (counter)
CLR R11 ;r10,r11:被开平方数扩展字节
LDI R17,$40
SQR0: SUB R12,R17
SBC R11,R9
SBC R10,R8
BRCS SQR1
SEC ;试根够减,本位根1
RJMP SQR2
SQR1: ADD R12,R17
ADC R11,R9
ADC R10,R8
CLC ;否则恢复被开平方数,本位根0
SQR2: DEC R16
BRNE SQR3 ;when the No.17bit of root be getting
SQR20: ADC R9,R15 ;R15 HAVE BEEN CLEARED!
ADC R8,R15
ADC R15,R15 ;将开出之根4舍5入,使根最大可达65536(=$10000)!
RET ;for example:sqr.($ffff0001)≈$10000
SQR3: ROL R9
ROL R8 ;记本位根
LSL R15
ROL R14
ROL R13
ROL R12
ROL R11
ROL R10 ;被开平方数连同
其扩展字节左移一位
LSL R15
ROL R14
ROL R13
ROL R12
ROL R11
ROL R10 ;被开平方数连同其扩展字节再次左移一位/左移2位开出1位根
BRCS SQR20 ;被开平方数左移2位后,若进位置位,则仅表明第17位根
;已被提前开出且该位根=1,将平方根增1,开平方结束。
RJMP SQR0 ;否则转试下一位根
;范例15 ;定点整数二翻十
CONV1: LDI R17,24 ;r12r13r14r15<--(r9r10r11)左移24次
MOV R7,R17 ;例:16777215<--$FFFFFF
CLR R12
CLR R13 ;68719476735<--$FFFFFFFFF
CLR R14 ;1099511627775<--$FFFFFFFFFF
CLR R15 ;十进制数存储区予清除
CV1: LSL R11
ROL R10
ROL R9 ;二进制数整体左移一位
MOV R16,R15
RCALL LSDAA
MOV R15,R16
MOV R16,R14
RCALL LSDAA
MOV R14,R16
MOV R16,R13
RCALL LSDAA
MOV R13,R16
MOV R16,R12
RCALL LSDAA ;十进制数左移并调整
MOV R12,R16
DEC R7
BRNE CV1
RET
;范例16 ;定点整数十翻二
CONV2: LDI R17,24 ;(r9r10r11)-->r13r14r15,右移24次
CLR R31 ;例:999999-->$0F423F
MOV R7,R17 ; 99999999-->$05F5E0FF
CV2: LSR R9
ROR R10
ROR R11
ROR R13
ROR R14
ROR R15 ;十进制数连同二进制数右移一位
LDI R30,12 ;数据指针
CV2L: LD R16,-Z
RCALL RSDAA ;十进制数右移调整
ST Z,R16
CPI R30,9 ;十进制数各字节调整完毕?
BRNE CV2L
DEC R7 ;右移次数(24次)完成?
BRNE CV2
RET
;范例17 ;定点小数二翻十
CONV3: LDI R17,24 ;(r13r14r15)--->r9r10r11r12右移24次
CONV31: MOV R7,R17
CLR R9
CLR R10 ;例:$0.FFFFFF-->0.99999994
CLR R11 ;$0.FFFFFFFF-->0.999999999767
CLR R12 ;$0.FFFFFFFFF->0.999999999985448
CLR R31
CV3: LSR R13
ROR R14
ROR R15
ROR R9
ROR R10
ROR R11
ROR R12 ;二进制数连同十进制数右移一位
LDI R30,9
CV3L: LD R16,Z
RCALL RSDAA ;十进制数右移调整
ST Z+,r16
CPI R30,13
BRNE CV3L ;十进制数各字节调整完毕?
DEC R7
BRNE CV3 ;右移次数(24次)完成?
RET
;范例18 ;定点小数十翻二
CONV4: LDI R17,32 ;r12r13r14r15<--r8r9r10r11<--(r12r13r14r15)
MOV R7,R17 ;左移32次
CV4: CLC ;例:$0.FFFFFFD5<--0.99999999
MOV R16,R15 ;$0.FFFFFFFF92<--0.9999999999
RCALL LSDAA
MOV R15,R16
MOV R16,R14
RCALL LSDAA
MOV R14,R16
MOV R16,R13
RCALL LSDAA
MOV R13,R16
MO
V R16,R12
RCALL LSDAA
MOV R12,R16 ;定点十进制小数左移并调整
ROL R11
ROL R10
ROL R9
ROL R8 ;定点二进制小数带进位位左移一位
DEC R7
BRNE CV4
MOV R12,R8 ;最终结果转入R12--R15
MOV R13,R9
MOV R14,R10
MOV R15,R11
RET
;范例19 ;等步距线性内插计算子程序
.EQU TBLGTH=10
CHETA: LDI R16,TBLGTH-1 ;r16<--表长(即字数)-1
LDI R31,HIGH(chtbl*2);y0(函数初值)在r14r15,STEP(步长)在r10r11,自变量X在r12r13
LDI R30,LOW(chtbl*2+1);查表指针,首指数据表第1字之高位字节!
RCALL CPMR1 ;X与表中第一个字型数据(X0)比较
BRCC CHRET ;X<X0 查表结束,Y=Y0
CHET1: RCALL CMPR1 ;X与表中下一个数据比较
BRCC NX33 ;X<X(i+1) 到插值区间
ADD R15,R11 ;否则Y0中加入一个STEP:Yk=Y0+k*step(步距为负时则
;
减去|STEP|)
ADC R14,R10
DEC R16
BRNE CHET1 ;未查到表格终值,循环;否则结束,Y取得最大值Yn
CHRET: RET
NX33: SBIW R30,5 ;指针退回(-5),指向Xi
MOV R8,R14
MOV R9,R15 ;保存Y0+i*STEP
RCALL SUBS ;(X-Xi)-->r16r17
MOV R15,R17
MOV R14,R16 ;转入r14r15
RCALL MUL16 ;(X-Xi)*STEP-->r12r13r14r15
MOV R10,R12
灵魂MOV R11,R13 ;保存乘积高位字
LPM ;X(i+1)低位字节
MOV R13,R0
ADIW R30,1
LPM ;X(i+1)高位字节
MOV R12,R0
SBIW R30,3 ;指针指向Xi
RCALL SUBS ;X(i+1)-Xi-->r16r17
MOV R12,R10
MOV R13,R11 ;取回乘积高位字
MOV R10,R16
MOV R11,R17 ;X(i+1)-Xi-->r10r11
RCALL DIV165 ;(X-Xi)*STEP/[X(i+1)-Xi]-->r14r15
ADD R15,R9
ADC R14,R8 ;Y0+i*STEP+(X-Xi)*STEP/[X(i+1)-Xi]-->r14r15
RET ;若STEP为负值则改为计算(r8r9)减去(r14r15)之值
CMPR1: LPM ;取数据高位字节
ADIW R30,2 ;指向下一数据的高位字节
CP R0,R12 ;与X高位字节相比较
BRNE CPRT1 ;不相等即转出
SBIW R30,3 ;否则调整指针
LPM ;取数据低位字节
ADIW R30,3 ;指向下一数据的高位字节
CP R0,R13 ;与X低位字节相比较
CPRT1: RET ;以进位C带回比较结果
SUBS: LPM ;计算(X-Xi)或[X(i+1)-Xi]并送入r16r17
MOV R5,R0 ;取Xi低位字节
ADIW R30,1
LPM ;取Xi高位字节
SBIW R30,1 ;仍指向Xi低位字节
SUB R13,R5
MOV R17,R13
SBC R12,R0
MOV R16,R12 ;计算差并将其转入R16R17
RET
;自变量x表长为12字云南开远惊现死亡地带
CHTBL:DW 19214,23404,27600,32799,37009,40211,45414,48618,51821,55029,57787,60070
;步距表长为11
字
STEPT: DW 356,366,379,395,415,440,471,509,555,603,657
;不等步距线性内插计算子程序,步距表首址在R6R7中
;自变量X在R12R13之中, 函数初值Y0在R14R15中
;
范例20 ;表长(字个数)-1在R16中
CHTSTP: LDI R31,HIGH(chtbl*2)
LDI R30,LOW(chtbl*2+1);查表指针
LDI R16,LOW(stept*2)
MOV R7,R16
LDI R16,HIGH(stept*2)
MOV R6,R16 ;步距表指针
LDI R16,TBLGTH-1 ;r16<--表长(字个数)-1
RCALL CMPR1 ;X与表首数据比较
BRCC CHSTPT ;X<X0 查表结束,有Y=Y0
CHSTP1: RCALL CMPR1 ;否则与表中下一数据比较
BRCC CHSTP3 ;X<X(i+1),到插值区间!
RCALL GTSTP ;查表取STEP字型变量
ADD R15,R11 ;Y0<--Y0+STEPk
ADC R14,R10
DEC R16
BRNE CHSTP1 ;未查到表格终值循环;否则结束,Y取得最大值Yn
CHSTPT: RET
CHSTP3: SBIW R30,5 ;指针退回,指向Xi低位字节
MOV R8,R14
MOV R9,R15 ;Y0+∑STEPk送入r14 r15
RCALL SUBS ;(X-Xi)->r16r17
MOV R15,R17
MOV R14,R16 ;(X-Xi)转入R14R15
RCALL GTSTP ;查表取STEPi-->R10R11
RCALL MUL16 ;(X-Xi)*STEPi-->R12R13R14R15
MOV R10,R12
MOV R11,R13 ;保存积高位字
LPM
MOV R13,R0
ADIW R30,1
LPM
MOV R12,R0
SBIW R30,3
RCALL SUBS ;(X(i+1)-Xi)-->r16 r17
MOV R12,R10
MOV R13,R11
MOV R10,R16
MOV R11,R17 ;取回积高位字 &(X(i+1)-Xi)-->r10r11
RCALL DIV165 ;(X-Xi)*STEPi/[X(i+1)-Xi]-->r14r15
ADD R15,R9 ;
ADC R14,R8 ;Y0+∑STEPk+(X-Xi)*STEPi/[X(i+1)-Xi]-->r14r15
RET
GTSTP: MOV R5,R6 ;查取STEP字型变量/POINTER in r6r7!
MOV R6,R30
MOV R30,R5
MOV R5,R7
MOV R7,R31
MOV R31,R5 ;(r6r7)<-->Z
LPM
MOV R11,R0
ADIW R30,1
LPM
MOV R10,R0 ;STEPk取到r10r11
ADIW R30,1
MOV R5,R6
MOV R6,R30
MOV R30,R5
MOV R5,R7
MOV R7,R31
MOV R31,R5 ;指针增2后送回r6r7
RET
;范例21 ;功能表程序
FUNC2: LDS R16,$A3 ;use r0,r8,r9,r10,r11,r16&r17/& subprogram dspa
SBR R16,$80 ;功能表程序标志
STS $A3,R16
LDI YH,2
LDI YL,0 ;功能内容表SRAM地址
RCALL FLFUNC ;CLR r27!
LDI R16,2
ST X,R16 ;显示'FUNC.2'
RCALL DL2S
CLR R9 ;功能内容寻址偏移量R9!
CLR R8 ;功能名称寻址偏移量(R8)=(r9)*3
FFUNC0: RCALL DSF_ ;显示'F- '
FF0: RCALL DSPA ;in subprogram dspy clr. r27!
CPI R16,11 ;回车键按下?
BRNE FF2P
FF0C: RCALL COMBNO ;合成功能名称送入r16
CPI R16,20 ;是最后一个功能名称?
BRNE FF1
CLR R9 ;是,两偏移量初