//双字节加法指令,将内部RAM 50H开始的2个单元中存放的2字节十六进制 //和内部RAM 60H单元开始的2个单元中存放的2字节十六进制相加 //结果存放在60H开始的单元中 DouByteAdd:: LDA $0051H //先取出低字节的数据进行相加 ADD $0061H //两个字节的低字节相加结果放在A中 STA $0061H //低字节相加的结果存放在$0041H中 LDA $0050H //取出高字节的数据 ADC $0060H //高字节数据相加 STA $0060H //高字节数据相加结果存放在$0040H RTS //功能:双字节减法指令。将内部RAM 50H开始的2个单元中存放的2字节十六进制 //和内部RAM 60H单元开始的2个单元中存放的2个字节十六进制数相减 //结果存放在60H开始的单元中 DouByteSub: LDA $0051H //取出被减数的低字节 SUB $0061H //和减数的低字节相减 STA $0061H //结果存放在减数的低字节位置 LDA $0050H //去被减数的高字节 SBC $0060H //和减数的高字节相减 STA $0060h //结果存放在减数高字节位置 RTS /标号:BCDA //功能:双字节BCD码加法 //入口条件:被加数在add1中,加数在add2中。 //出口信息:和在add1中。 BCDA:: count: blkb 1 //字节的个数,如果改变这个参数可以实现多字节BCD码加法 LDA #2 STA count //设置循环次数 LDA #add1 //初始化被加数指针,从低位开始运算 ADD count //将add1的指针指到最低字节处 STA add1 LDA #add2 //初始化加数指针,从低位开始运算 ADD count //将add2的指针指到最低字节处 CLC //清进位标志位 BCLR 4,CCR //清半进位标志 lable1:DBNZ count ,loop //确定循环次数 JMP BCDA_EXIT loop: DEC add1 //将被加数移到相应字节 DEC add2 //将加数移到相应字节 LDA add1 ADDC add2 DDA //十进制调整 STA add1 //存放相应字节运算结果 BCLR 4,CCR //清半进位标志 JMP label1 BCDA_EXIT: RTS //① 求BCD减数的双字节补数公式:999AH-减数。这里的999AH代表四位BCD码的模1000。 //② 被减数加上减数的补数。 //③ 对第②步的加法之和进行十进制加法调整,调整结果即为所求的减法结果。 //标号:BCDSUB //功能:双字节字节BCD码减法 //入口条件:被减数在add1中,减数放在add2中 BCDSUB:: LDHX add2 //取得减数 JMP BCD_NEG //求减数的补数 JMP BCD //调用BCD码双字节加法子程序
RTS //标号:BCD_NEG //功能:对BCD码求补 //入口条件:将add2中所存放的BCD码转换成补码 //原理:3字节BCD码的模位99999A,4字节BCD码的模位:9999999A,因此求多字节BCD // 码的补数时,只要将最后一位单独处理即可,高位用循环求 //出口参数:add2中存放求补之后的BCD码 BCD_NEG:: count : blkb 1 //字节的个数 MOV #2 , count //设置循环次数 LDA #add2 //初始化add2的指针,将其指向最低地址处 ADD count DEC count //字节数减1 CLC //清进位标志位 //求最低一字节BCD码的补码 DEC add2 //将add2指针指到最低一字节 LDA #0x9AH SBC add2 STA add2 //求得最低一字节BCD补码 //求高字节BCD码的补码 lable1:DBNZ count ,loop //确定循环次数 JMP BCD_NEG_EXIT loop: LDA #0X99H SBC add2 LDA add2 INC add2 JMP label1 BCD_NEG_EXIT: RTS //一个延时子程序,用来延时1000个指令周期 Delay: LDA #200 //延时约200 5 = 1000(T)---- Delay_1: NOP //(1T) NOP //(1T) DBNZA Delay_1 //(3T) AIX #-1 CPHX #0 BNE Delay //=========================== DelayHX_Exit: PULA //A出栈(恢复寄存器A) RTS
一样吧看最后一句
最后,相加的情况,如果你的比如是分开的,就直接相加就好 如果你的值是同一个数字的就按位乘以256,如 0x02 256 256 + 0x03 256 + 0xff 什么,你说太长了那就用循环处理,判断好是几位的就行了,或再独立写个小方法,也用传参的方式把值和第几位传进去什么你说和其它的值相加,那对着位置加上去就行了(如高位对高位,低位对低位,溢出位,往上加就好
(一)MCS-51定点运算子程序库及其使用说明
定点运算子程序库文件名为DQ51ASM,为便于使用,先将有关约定说明如下:
1.多字节定点 *** 作数:用[R0]或[R1]来表示存放在由R0或R1指示的连续单元中的数据。地址小的单元存放数据的高字节。例如:[R0]=123456H,若(R0)=30H,则(30H)=12H,(31H)=34H,(32H)=56H。
2.运算精度:单次定点运算精度为结果最低位的当量值。
3.工作区:数据工作区固定在PSW、A、B、R2~R7,用户只要不在工作区中存放无关的或非消耗性的信息,程序就具有较好的透明性。
(1) 标号: BCDA功能:多字节BCD码加法
入口条件:字节数在R7中,被加数在[R0]中,加数在[R1]中。
出口信息:和在[R0]中,最高位进位在CY中。
影响资源:PSW、A、R2 堆栈需求: 2字节
BCDA: MOV A,R7 ;取字节数至R2中
MOV R2,A
ADD A,R0 ;初始化数据指针
MOV R0,A
MOV A,R2
ADD A,R1
MOV R1,A
CLR C
BCD1: DEC R0 ;调整数据指针
DEC R1
MOV A,@R0
ADDC A,@R1 ;按字节相加
DA A ;十进制调整
MOV @R0,A ;和存回[R0]中
DJNZ R2,BCD1 ;处理完所有字节
RET
MBCOM:
SETB C ;(为什么)为了加一
LOOP:
MOV A, @R0
CPL A
ADDC A, #0 ;--把C加进去
MOV @R0, A
INC R0 ;(为什么)为了转向下一个地址
DJNZ R3, LOOP
DEC R0
RET
;修改'899',和'999'的长度,即可计算任意长度的相加
;如d10 db '18929387499'
; d12 db '18234287439'
; 补充,这是相加,你要求是相减,搞差了,减法的附在后面
dseg segment
d10 db '899'
len1 equ $-d10 ;注意 d10与d12长度相同,可以做不同,但比较麻烦,这里没做
d11 db '+'
d12 db '999' ;长度与d10相同
d13 db '=','$'
d2 db len1+1 dup(0),'$'
dseg ends
assume cs:cseg, ds:dseg
cseg segment
start:
mov ax, dseg
mov ds, ax
mov ah,9
lea dx, d10
int 21h
lea si, d10
lea di, d12
lea bx, d2
add si, len1-1 ;指向个位数位置
add di, len1-1 ;指向个位数位置
add bx, len1 ;指向个位数位置
mov cx, len1 ;计算器
clc ;清除cf
c0:
mov ah,0 ;清除ah
mov al,[si] ;取对应位置上的数字相加
and al,0FH ;
mov dl,[di] ;
and dl,0FH ;
add al,dl ;相加
aaa ;调整
add al,[bx] ;加上可能的进位
aaa ;再调整
mov [bx],al ;保存到对应的位置上
mov [bx-1],ah;可能存在的进位,保存到对应的位置上
dec si ;下一位相加
dec di
dec bx
loop c0
mov cx, len1+1
lea bx, d2
c1:
xor byte ptr [bx], 30H ;将结果转换为ascII值
inc bx
loop c1
mov cx, len1
lea bx, d2
c2:
mov al, [bx] ;查找结果中,第1个结果不是0的数字
cmp al, 30H ;从此开始显示结果,以免出现0123这样的结果
jnz p0
inc bx
loop c2
p0:
mov dx,bx
mov ah,9
int 21h
mov ah,4ch
int 21h
cseg ends
end start
;这是减法的代码
;有个bug,被减数必须大于减数时才正确。
;暂时先这样
dseg segment
d10 db '991'
len1 equ $-d10 ;注意 d10与d12长度相同,可以做不同,但比较麻烦,这里没做
d11 db '-'
d12 db '192' ;长度与d10相同
d13 db '=','$'
d2 db len1+1 dup(0),'$'
dseg ends
assume cs:cseg, ds:dseg
cseg segment
start:
mov ax, dseg
mov ds, ax
mov ah,9
lea dx, d10
int 21h
lea si, d10
lea di, d12
lea bx, d2
add si, len1-1 ;指向个位数位置
add di, len1-1 ;指向个位数位置
add bx, len1 ;指向个位数位置
mov cx, len1 ;计算器
clc ;清除cf
c0:
mov ah,0 ;清除ah
mov al,[si] ;取对应位置上的数字相加
and al,0FH ;
mov dl,[di] ;
and dl,0FH ;
sub al,[bx] ;减去可能的借位
aas ;再调整
sub al,dl ;相减
aas ;调整
neg ah ;如有借位,转换为正数1
mov [bx],al ;保存到对应的位置上
mov [bx-1],ah;可能存在的进位,保存到对应的位置上
dec si ;下一位相加
dec di
dec bx
loop c0
mov cx, len1+1
lea bx, d2
c1:
xor byte ptr [bx], 30H ;将结果转换为ascII值
inc bx
loop c1
mov cx, len1
lea bx, d2
c2:
mov al, [bx] ;查找结果中,第1个结果不是0的数字
cmp al, 30H ;从此开始显示结果,以免出现0123这样的结果
jnz p0
inc bx
loop c2
p0:
mov dx,bx
mov ah,9
int 21h
mov ah,4ch
int 21h
cseg ends
end start
评论列表(0条)