很遗憾,该程序只能接收-127--128的数字进行运算,否则输出为0(在masm5下测试无误)
看不明白再来问。
.model small
.stack 100
.data
prompt1 db 'Please enter a integer(-127--128)!',0dh,0ah,'$'
prompt2 db 'The product is: ' ,0dh,0ah,'$'
input_str db 10
db ?
db 8 dup (?) ;10号中断接收数字串的地址
db 0dh,0ah,'$'
buff_str db 10 dup (?)
db 0dh ,0ah,'$'
.code
_start:
mov ax,@data
mov ds,ax ;数据段初始化
mov dx,offset prompt1
mov ah,9
int 21h ;提示用户输入
mov dx,offset input_str
mov ah,10
int 21h ;接收用户输入
mov bx,offset input_str+2
push bx ;参数进栈
call atoiproc ;将用户输入的数字串转换为数值放到ax中
mov cx,20
imul cx ;求积
mov bx,offset buff_str ;itoaproc的一参数,存放ax的值转换成的数字串
push ax ;积作为参数进栈
push bx ;存放ax的值转换成的数字串
call itoaproc ;将进栈的值转换为数字串放到bx开始的内存
mov dx,offset prompt2
mov ah,9
int 21h
mov dx,offset buff_str
mov ah,9
int 21h ;输出结果
mov ah,7
int 21h ;等待用户按任意键结束程序
mov ah,4ch
int 21h
;----------------------------;数字转化成数字串子程序-----------------------------------
itoaproc proc near
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push di
pushf
mov ax,[bp+6]
mov di,[bp+4]
ifSpecial:
cmp ax,8000h
jne EndIfSpecial
mov BYTE PTR [di],'-'
mov BYTE PTR [di+1],'3'
mov BYTE PTR [di+2],'2'
mov BYTE PTR [di+3],'7'
mov BYTE PTR [di+4],'6'
mov BYTE PTR [di+5],'8'
jmp ExitIToA
EndIfSpecial:
mov dx, ax
mov al,' '
mov cx,5 ; first five
cld ; bytes of
rep stosb ; destination field
mov ax, dx ; copy source number
mov cl,' ' ; default sign (blank for +)
IfNeg: cmp ax,0 ; check sign of number
jge EndIfNeg ; skip if not negative
mov cl,'-' ; sign for negative number
neg ax ; number in AX now >= 0
EndIfNeg:
mov bx,10 ; divisor
WhileMore: mov dx,0 ; extend number to doubleword
div bx ; divide by 10
add dl,30h ; convert remainder to character
mov [di],dl ; put character in string
dec di ; move forward to next position
cmp ax,0 ; check quotient
jnz WhileMore ; continue if quotient not zero
mov [di],cl ; insert blank or "-" for sign
ExitIToA: popf ; restore flags and registers
pop di
pop dx
pop cx
pop bx
pop ax
pop bp
ret 3 ;exit, discarding parameters
itoaproc ENDP
;;;------------------------;数字串转换为数字子程序------------------------------
atoiproc PROC NEAR
push bp ; save base pointer
mov bp, sp ; establish stack frame
sub sp, 2 ; local space for sign
push bx ; Save registers
push cx
push dx
pushf ; save flags
mov si,[bp+4] ; get parameter (source addr)
WhileBlank: cmp BYTE PTR [si],' ' ; space?
jne EndWhileBlank ; exit if not
inc si ; increment character pointer
jmp WhileBlank ; and try again
EndWhileBlank:
mov ax,1 ; default sign multiplier
IfPlus: cmp BYTE PTR [si],'+' ; leading + ?
je SkipSign ; if so, skip over
IfMinus: cmp BYTE PTR [si],'-' ; leading - ?
jne EndIfSign ; if not, save default +
mov ax,-1 ; -1 for minus sign
SkipSign: inc si ; move past sign
EndIfSign:
mov [bp-1],ax ; save sign multiplier
mov ax,0 ; number being accumulated
mov cx,0 ; count of digits so far
WhileDigit: cmp BYTE PTR [si],'0' ; compare next character to '0'
jl EndWhileDigit ; not a digit if smaller than '0'
cmp BYTE PTR [si],'9' ; compare to '9'
jg EndWhileDigit ; not a digit if bigger than '9'
mov dl,10
imul dl ; multiply old number by 10
jo overflow ; exit if product too large
mov bl,[si] ; ASCII character to BL
and bx,000Fh ; convert to single-digit integer
add ax,bx ; add to sum
jc overflow ; exit if sum too large
inc cx ; increment digit count
inc si ; increment character pointer
jmp WhileDigit ; go try next character
EndWhileDigit:
cmp cx,0 ; no digits?
jz overflow ; if so, set overflow error flag
; if value is 8000h and sign is '-', want to return 8000h (-32,768)
cmp ax,8000h ; 8000h ?
jne TooBig?
cmp WORD PTR [bp-1],-1 ; multiplier -1 ?
je ok1 ; if so, return 8000h
TooBig?: test ax,ax ; check sign flag
jns ok ; will be set if number > 32,767
overflow: pop ax ; get flags
or ax,0000100001000100B ; set overflow, zero & parity flags
and ax,1111111101111110B ; reset sign and carry flags
push ax ; push new flag values
mov ax,0 ; return value of zero
jmp AToIExit ; quit
ok: imul WORD PTR [bp-1] ; make signed number
ok1: popf ; get original flags
test ax,ax ; set flags for new number
pushf ; save flags
AToIExit: popf ; get flags
pop dx ; restore registers
pop cx
pop bx
mov sp, bp ; delete local variable space
pop bp
ret 2 ; exit, removing parameter
atoiproc ENDP
;------------------------------------------------------------------------------------
end _start
end