cseg segment
hextab db '0123456789ABCDEF'
A dd 11118888H
b dd 33339444H
c dd 0
start:
mov ax, cseg
mov ds, ax
mov ax, word ptr a
add ax, word ptr b
mov word ptr c, ax
mov ax, word ptr a+2
adc ax, word ptr b+2
mov word ptr c+2, ax
16进制显示结果
lea bx, hextab
mov ah, 0eh
高16位
mov dx, word ptr c+2
mov cx, 404h
c1:
rol dx, cl
mov al, dl
and al, 0fh
xlat
int 10h
dec ch
jnz c1
低16位
mov dx, word ptr c
mov cx, 404h
c2:
rol dx, cl
mov al, dl
and al, 0fh
xlat
int 10h
dec ch
jnz c2
mov ah,4ch
int 21h
cseg ends
end start
DATA SEGMENTSUM1_100 DW 0 保存1加到100
SUMEVEN DW 0 100以内的偶数和
SUMODD DW 0 100以内的奇数和
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
MOV CX,1
LP0:
ADD SUM1_100,CX
TEST CX,01H 判断偶数还是奇数
JZ ODD
ADD SUMEVEN,CX
JMP NEXT
ODD:
ADD SUMODD,CX
NEXT:
INC CX
CMP CX,100
JBE LP0
MOV AX,4C00H
INT 21H
CODE ENDS
END START
.MODEL SMALL.DATA
X1 DB '1234567890123456'16位的十进制被加数
X2 DB '9233445566778899'16位的十进制加数
Y1 DB '00000000000000000' 17位的十进制加法的和(考虑最高位可能有进位产生)
.CODE
.STARTUP
LEA SI, X1
LEA DI, X2
LEA BX, Y1
ADD SI, 15SI 指向被加数的最右端的个位数
ADD DI, 15DI 指向加数的个位数
ADD BX, 16 BX 指向加法的和的个位数
MOV CX, 16循环16次
CLC 运算前将CF清0
PUSHF PSW标志寄存器入栈保存
AGAIN:
POPFPSW标志寄存器出栈,恢复CF
MOV AL, [SI] 取被加数到AL
ADC AL, [DI]将加数加到AL中
AAA非压缩的BCD码(即ASCII码)加法调整
MOV [BX], AL保存加得的和
PUSHFPSW标志寄存器入栈,主要是为了保存好CF标志
AND BYTE PTR [BX], 0FH 将这一位加法的和的高4位清零
ADD BYTE PTR [BX], 30H 将这一位加法的和调整成数字的ASCII码
DEC SI调整指针,处理下一位
DEC DI
DEC BX
LOOP AGAIN
POPF这一小段指令处理最后的进位形成的第17位
MOV AL, 0
ADC AL, 0
ADD AL, 30H
MOV [BX], AL
.EXIT
END
程序说明:
1. 很长的整数,直接按每一位用一个字节的数字字符的ASCII码存储,16位的十进制数就是一个由16个数字字符构成的字符串
2. 加法运算,是将每个ASCII字符看成是非压缩的BCD码,在AL中进行过加法运算后,用非压缩的BCD码调整指令将结果调整成非压缩的BCD码格式,加法的进位保存在CF中。运算规则完全按照手工计算的方法进行,依个位、十位、百位……的次序从右向左逐位相加,在相加时带上上一位的进位。程序共循环16次。
3. 为了避免指针调整和循环控制时CF被这些运算结果所修改,造成运算结果错误,需要用堆栈保存PSW的方法保护CF,运算结果调整好以后立即保存CF,下次运算前恢复CF。
4. 程序只考虑了运算,没有考虑显示。可以在调试程序中查看运算结果是否正确。若需要加上显示功能,对数据段的定义稍加修改,用09H号DOS系统功能调用即可。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)