。model small
。stack 8192
。data
x dw -99
y dw 50
。
code
main: mov ax,@data
mov ds,ax
mov ax,x ;ax=x
dec ax ;ax=x-1
imul y ;带符号数整数乘法 dx:ax=ax*y
call ?slong
mov ah,4ch
int 21h
putc proc
push ax
mov ah,2
int 21h
pop ax
ret
putc endp
puts proc
push ax
mov ah,9
int 21h
pop ax
ret
puts endp
?slong proc ;?slong 输出DX:AX里的带符号数;?ulong 输出DX:AX里的无符号数
test dx,8000h ;是负数?
jz ?ulong ;否转无符号版本直接输出
push ax
push dx
mov dl,'-' ;先输出个负号
call putc
pop dx
push dx
call neg32 ;取相反数
call ?ulong ;输出相反数
pop dx
pop ax
ret
?ulong: push ax ;输出DX:AX里的无符号数
push bx
push cx
push dx
call @f
pop dx
pop cx
pop bx
pop ax
ret
@@: push ax
or ax,dx ;是0则直接输出
pop ax
jnz @f
mov dl,'0'
call putc
ret
@@: mov bx,ax ;把低16位先存一个到BX
mov ax,dx
xor dx,dx
mov cx,10
div cx ;高16位除以10
push ax ;留存高16位的商
mov ax,bx ;高16位的余数(已经在DX里了)
div cx ;和低16位再一块除以10
mov cx,ax ;低16位的商存个在CX里
or cx,dx ;若商与余数都为0则结束递归,跳转前先要留存结果等等
mov cx,dx ;留存DX中的余数以在递归后输出
pop dx ;恢复高16位的商,至此,DX:AX里是刚才整个除法的商,CX是余数
jz @f
push cx ;留存刚才DX:AX除10的余数,就是个位数,以在递归后输出(输出则是倒过来的)
call @b ;递归
pop dx ;从最高位的余数开始恢复并输出
add dl,'0'
call putc
@@: ret
?slong endp
neg32 proc ;注意对0x80000000(-2,147,483,648)返回的是CF=1且dx:ax不变(因为正值是溢出的)
cmp dx,8000h
jne @f
or ax,ax
jnz @f
stc
ret
@@: neg dx
neg ax
sbb dx,0
clc
ret
neg32 endp
end main。
全部