代码在masm5下测试通过,只能进行-127~~128之间的加法且结果不能超出-127~~128 这是因为受到程序里面那两个过程(itoaproc & atoiproc)的限制。
下班了来不及写注释和详细解释,明天来补充!
data segment
msg DB 'please keyin the first integer : ', '$'
msg2 DB 'please keyin the second integer :', '$'
msg3 DB 'x+y='
out_buffer db 4 dup(?)
db '$','$'
newline DB 13, 10, '$'
first_number db 4
db ?
db 2 dup(?)
second_number db 4
db ?
db 2 dup(?)
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
xor ax,ax
MOV AH, 09H
MOV DX, offset msg
INT 21H
mov dx,offset first_number
mov ah,10
int 21h
add dx,2
mov bx,dx
push bx
call atoiproc
xor cx,cx
mov cx,ax
MOV DX, offset newline
MOV AH, 09H
INT 21H
MOV DX, offset msg2
MOV AH, 09H
INT 21H
mov dx,offset second_number
mov ah,10
int 21h
add dx,2
mov bx,dx
push bx
call atoiproc
add ax,cx
mov bx,offset out_buffer
push ax
push bx
call itoaproc
MOV DX, offset newline
MOV AH, 09H
INT 21H
mov dx,offset msg3
mov ah,9
int 21h
mov ah,7
int 21h
mov ah,4ch
int 21h
;;--------------------------------------------------------------------------
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
;;------------------------------------------------------------------------
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
;;---------------------------------------------------------------------------
code ends
end start