;输入大整数,将其反序并由ASCII码值转换成数值,输入以非数字字符为结束符。
;输出大整数,将大整数反序,并转为ASCII码
ASSUME SS:stack1
stack1 SEGMENT STACK
DB 256 DUP(?)
stack1 ENDS
;子程序1:输入大整数,将其反序并由ASCII码值转换成数值,输入以非数字字符为结束符。
;入口参数:ES,DI,SI
;ES存放主函数的段地址,DI存放待处理大整型字符串的首地址,SI存放主调函数中长度变量的地址。
;出口:修改大整型和长度变量的值
;用到的寄存器:AX,DS,DI,CX,BX,SI,ES
data2 SEGMENT
temp DB 128 DUP(0)
addrBI DW ? ;存放传递过来的大整型字符串的首地址
addrLEN DW ? ;存放传递过来的长度变量的地址
data2 ENDS
code2 SEGMENT
inBI PROC FAR ;input bigint
ASSUME CS:code2,DS:data2
;BEGIN寄存器保护
PUSH AX
PUSH DS
PUSH DI
PUSH CX
PUSH BX
PUSH SI
PUSH ES
;END
MOV AX,data2
MOV DS,AX
;保存主调函数传递过来的变量的地址
MOV [addrBI],DI
MOV [addrLEN],SI
;BEGIN:输入模块
LEA DI,temp
MOV CL,0 ;记录大整数的位数
MOV BL,1 ;是否是首位,若首位是0,则继续是首位。1表示是首位,0表示不是
again2_1:
MOV AH,1
INT 21H
CMP AL,'0'
JB over2_1
CMP AL,'9'
JA over2_1
CMP BL,1 ;是否位首位
JNE NotFirst ;若不为首位,则继续往下
CMP AL,'0'
JE again2_1 ;为首位,且首位为0,则忽略0,继续输入
NotFirst:
MOV BL,0 ;将标志更改为“不是首位”
MOV [DI],AL
INC DI
INC CL
JMP again2_1
over2_1:
CMP AL,0DH ;如果是以Enter结束输入,则先输出一个换行符
JNE NotCR
MOV DL,0AH
MOV AH,02H
INT 21H
;END:输入模块结束
NotCR: MOV AX,DI ;临时保存DI
MOV DI,[addrLEN]
MOV ES:[DI],CL ;保存大整数长度
MOV DI,AX
DEC DI
MOV SI,[addrBI]
again2_2:
MOV AL,[DI]
SUB AL,30H
MOV ES:[SI],AL
DEC DI
INC SI
DEC CL
CMP CL,0
JNE again2_2
;BEGIN:寄存器恢复
POP ES
POP SI
POP BX
POP CX
POP DI
POP DS
POP AX
;END
RET
inBI ENDP
code2 ENDS
;子程序2:输出大整数,将大整数反序,并转为ASCII码
;入口参数:ES,DI,SI
;ES:主调函数的数据段段地址;DI:主调函数中大整型变量的首地址;SI:主调函数中大整型长度变量的地址。
;出口:修改大整型变量
;用到的寄存器:AX,DS,CX,DI,SI,DX,ES
data3 SEGMENT
addrBI2 DW ? ;存放传递过来的大整型的首地址
addrLEN2 DW ? ;存放传递过来的大整型长度变量的地址
data3 ENDS
code3 SEGMENT
outBI PROC FAR ;output bigint
ASSUME CS:code3,DS:data3
;BEGIN寄存器保护
PUSH AX
PUSH DS
PUSH CX
PUSH DI
PUSH SI
PUSH DX
PUSH ES
;END
MOV AX,data3
MOV DS,AX
;用内存变量保存主调函数变量的地址
MOV [addrBI2],DI
MOV [addrLEN2],SI
MOV CL,ES:[SI]
MOV SI,DI ;DI存放的是传递过来的大整型的偏移地址
MOV CH,0
ADD SI,CX
DEC SI ;SI指向bigInt尾
again3_1:
CMP SI,DI
JB over3_1 ;SI往回移动,DI往前移动,如果DI移动到SI前面,则循环停止
;如果这里用JNA,则当长度为奇数时,最中间的数没有转为ASCII码
;若为JAN,输入:1234567890123456789,12345678901,结果就会有问题
MOV AH,ES:[SI]
ADD AH,30H
MOV AL,ES:[DI]
ADD AL,30H
MOV ES:[SI],AL
MOV ES:[DI],AH
DEC SI
INC DI
JMP again3_1
over3_1:
MOV DI,[addrBI2]
MOV DX,DI
ADD DI,CX
MOV ES:[DI],'$(编译时去掉此处括号)'
MOV AX,ES
PUSH DS
MOV DS,AX ;INT 21H的9号功能默认DS:DX,所以除了修改DX的值外,还要修改DS的值
MOV AH,09H
INT 21H
POP DS ;养成良好的编程习惯,恢复DS
;BEGIN:寄存器恢复
POP ES
POP DX
POP SI
POP DI
POP CX
POP DS
POP AX
;END
RET
outBI ENDP
code3 ENDS
;主程序
data1 SEGMENT
bigInt DB 128 DUP(0)
len DB 0
data1 ENDS
code1 SEGMENT
ASSUME CS:code1,DS:data1
start: MOV AX,data1
MOV DS,AX
;调用大整数输入函数
MOV ES,AX ;传递段地址给子函数
LEA DI,bigInt ;传递变量bigInt的偏移地址给子函数
LEA SI,len ;传递变量len的偏移地址给子函数
CALL FAR PTR inBI
;输出换行符和回车符
MOV DL,0AH
MOV AH,02H
INT 21H
MOV DL,0DH
MOV AH,02H
INT 21H
;调用大整数输出函数
MOV AX,data1
MOV ES,AX ;传递段地址给子函数
LEA DI,bigInt ;传递变量bigInt的偏移地址给子函数
LEA SI,len ;传递变量len的偏移地址给子函数
CALL FAR PTR outBI
MOV AH,4CH
INT 21H
code1 ENDS
END start