汇编问题,请高手指教
从键盘输入N个十进制数,求它们的和(累加和要求不大于65535),并将累加结果在屏幕上显示出来。要求给出必要的提示信息(用宏调用完成);累加功能由子程序调用实现;二进制数形式的累加和转换为十进制数并显示由子程序调用实现。
从键盘输入N个十进制数,求它们的和(累加和要求不大于65535),并将累加结果在屏幕上显示出来。要求给出必要的提示信息(用宏调用完成);累加功能由子程序调用实现;二进制数形式的累加和转换为十进制数并显示由子程序调用实现。
答案:;从键盘输入N个十进制数(数与数之间用空格隔开),以回车结束
;求它们的和(累加和要求不大于65535),
;并将累加结果在屏幕上显示出来。
;----------------------------------------------
DISP_STR MACRO X ;宏定义.
MOV DX, OFFSET X
MOV AH, 9
INT 21H
ENDM
;----------------------------------------------
DATA SEGMENT ;数据段.
MSG1 DB 13, 10, 'Please Input : $'
MSG2 DB 13, 10, 'I can not count so much ! $'
MSG3 DB 13, 10, 'The SUM is : $'
x DW ? ;存放新输入数据.
y DW ? ;求和.
DATA ENDS
;----------------------------------------------
CODE SEGMENT ;代码段.
ASSUME CS: CODE, DS: DATA
START:
MOV AX, DATA
MOV DS, AX
;--------------------------------
DISP_STR MSG1 ;宏调用,提示 Please Input :
MOV y, 0 ;和 清零.
;--------------------------------
IN_LOOP:
MOV x, 0 ;数据清零.
_INX:
MOV AH, 1 ;输入字符.
INT 21H
CMP AL, 13 ;回车?
JZ _IN_END ;全部数字结束.
CMP AL, ' ' ;空格?
JZ _INY ;本数字结束.
CMP AL, 30H
JB _IN_ERR ;小于'0',输入错误.
CMP AL, 3AH
JNB _IN_ERR ;大于'9',输入错误.
;--------------------------------
SUB AL, 30H
MOV AH, 0
MOV CX, AX
MOV AX, x
MOV BX, 10 ;老数据乘以10
MUL BX
AND DX, DX
JNZ _IN_ERR ;输入过大,错误.
ADD AX, CX ;加上新数据.
JC _IN_ERR
MOV x, AX ;保存.
JMP _INX ;继续输入.
;--------------------------------
_INY:
MOV AX, x ;完整的新数据.
ADD AX, y ;求和.
JC _IN_ERR
MOV y, AX ;保存.
JMP IN_LOOP ;继续输入.
;--------------------------------
_IN_END:
DISP_STR MSG3 ;宏调用,提示 The SUM is :
MOV AX, x
ADD AX, y
CALL PRINTAX ;调用显示子程序
JMP EXIT
;--------------------------------
_IN_ERR:
DISP_STR MSG2 ;宏调用,提示 can not count so much !
EXIT:
MOV AH, 4CH
INT 21H
;--------------------------------
PRINTAX PROC
MOV BX, 10
OR AX, AX
JZ _0_
LOOP_P:
XOR DX, DX
DIV BX
MOV CX, AX ;商.
OR CX, DX
JZ _E_
PUSH DX
CALL LOOP_P ;递归.
POP DX
ADD DL, '0'
JMP _1_
_0_:MOV DL, '0'
_1_:CALL PUTC
_E_:RET
PRINTAX ENDP
;------------------------------
PUTC PROC
MOV AH, 2
INT 21H
RET
PUTC ENDP
;------------------------------
CODE ENDS
END START
;======================================
其他:;从键盘输入N个十进制数(数与数之间用空格隔开),回车求它们的和(累加和要求不大于65535),并将累加结果在屏幕上显示出来。
;
;
;用MASM 5.0 编译通过。(ESC退出)
;运行结果示范如下:
;E:\masm1>ins2
;11 22 33
;Sum all: 00066
;1 65534
;Sum all: 65535
;1 65535
;Sorry,too big!
data segment
sum1 db 0dh,0ah,"Sum all: "
sum2 db 5 dup (" "),0DH,0AH,'$' ;定义结果输出串,其中0DH,0AH相当于回车换行
crlf db 0dh,0ah,'$' ;输出回车换行
sum dw 0 ;和
temp dw 0 ;输入的数
s1 db '0123456789'
LL EQU $-S1
s2 db 0dh,0ah,'Sorry,too big! ',0dh,0ah,'$'
data ends
code segment
assume cs:code, ds:data
main proc far
start:
push ds
xor ax,ax
push ax
mov ax,data
mov ds,ax
PUSH DS
POP ES
;-------------------------
ini: ;初始化
mov ax,0
mov sum,ax
mov temp,ax
n1: ;输入字符起始位
mov ah,8
int 21h
cmp al,1bh ;ESC则结束
jnz goon
ret
goon:
cmp al,0DH ;是回车则输出结果
jnz goon2
mov bx,SUM
ADD BX,TEMP ;必须加上已输入但没有按空格的这个数
jnc noover1
JMP mul_over
noover1:
;jmp output
call print_c
jmp ini
goon2:
cmp al," " ;是" "则SUM=SUM+TEMP
jnz goon1
PUSH AX ;显示" "字符
MOV DL,AL
MOV AH,2
INT 21H
POP AX
MOV AX,TEMP
ADD AX,SUM
JNC SUM22
JMP mul_over
SUM22:
MOV SUM,AX
XOR AX,AX
MOV TEMP,AX
JMP N1
goon1:
CALL C_1 ;检测输入字符是否合法
JNZ N1 ;不合法,直接重新输入
mov ah,0
PUSH AX ;显示输入的字符
MOV DL,AL
MOV AH,2
INT 21H
mov bx,temp ;将上一位输入的数乘以10,再加上这次输入的数
mov ax,10
mul bx
cmp dx,0 ;如果上一位输入的数乘以10后(dx<>0),溢出。
jnz mul_over
pop bx
sub bl,'0'
add ax,bx ;如果AX有进位,溢出。
jc mul_over
jmp no_over
mul_over:
mov ah,9 ;数据溢出。
mov dx,offset s2
int 21h
jmp ini
no_over:
mov temp,ax
JMP N1
main endp
;==================
C_1 PROC NEAR ;检测输入的字符是否合法子程序
MOV DI,OFFSET S1
MOV CX,LL
REPNZ SCASB
ret
;返回:NZ=输入的值不在表内 ZR=输入的值在表内
C_1 ENDP
;===========
;=====================
print_c proc near ;显示结果子程序. 将和转换成10进制数并显示。
;实质是将存放和的BX依次除以10000、1000、100、10,然后依次显示其商及最后的余数
mov di,offset sum2 ;存放10进制显示串的起始地址
mov ax,bx ;BX是和,也就是要转换的被除数,放入AX
mov bx,10000 ;10000是第一个除数,因为AX的最大值是65535
mov dx,0 ;当除数是16位的BX时,被除数是DX:AX,所以DX必须置0
div_again:
div bx ;DX:AX/BX
cmp bx,10 ;当BX=10时结束转换
jnz save
add al,30h ;10位
mov [di],al
inc di
add dl,30h
mov [di],dl ;个位
jmp disp ;转显示
save:
add al,30h
mov [di],al ;保存商位
inc di
push dx ;余数继续除
mov dx,0
mov ax,bx
mov bx,10 ;需将除数依次缩小10倍(即:10000、1000、100、10),所以每次要要除10
div bx
mov bx,ax
pop ax
xor dx,dx
jmp div_again
disp:
mov ah,9 ;显示结果
mov dx,offset sum1
int 21h
ret
print_c endp
;======================
code ends
end start
上一个:哪位汇编高手能帮我“用汇编语言求两个数的最小公倍数和最大公约数”?
下一个:在线作业急等!!!!用汇编语言将内存中的16位的有符号二进制数转换为十进制ASCII码形式