我们采用分段的思想,每一段完成特定的功能,这样代码结构清晰,内容易懂。
一、首先贴代码如下
assume cs:code,ds:data
data segment
string db 20 ;用于定义一个缓冲区
db ?
db 20 dup(0)
number dw ?
res db 20 dup(0)
data ends
code segment
start:
mov ax,data
mov ds,ax
lea dx,string ;输入字符串
mov ah,0ah
int 21h
mov dx,0ah ;将光标移到下一行的开始处
mov ah,02h
int 21h
mov al,string+1
add al,2
mov ah,0
mov si,ax
mov string[si],'$'
cmp string[2],'-'
jnz positive
jz negative
positive:
mov dx,0
mov cl,string[1]
mov ch,0
dec cx
mov di,2
mov bx,0
and cx,cx
jz processlast
s0:
mov ax,10
sub string[di],30h
push dx;将dx的值保护起来
mov bh,0
mov bl,string[di]
add dx,bx
mul dx ;一定的,因为中间结果有可能超过8位的储存范围
pop dx
mov dx,ax
inc di
loop s0
processlast:
sub string[di],30h
mov bl,string[di]
mov bh,0
add dx,bx
jmp process
negative:
mov dx,0
mov cl,string[1]
mov ch,0
sub cx,2
mov di,3
mov bx,0
and cx,cx
jz processlast1
s1:
mov ax,10
sub string[di],30h
push dx;将dx的值保护起来
mov bh,0
mov bl,string[di]
add dx,bx
mul dx ;一定的,因为中间结果有可能超过8位的储存范围
pop dx
mov dx,ax
inc di
loop s1
processlast1:
sub string[di],30h
mov bl,string[di]
mov bh,0
add dx,bx
neg dx
jmp process
process:
mov number,dx
shl dx,1
jnc ispositive
jc isnegative
isnegative:
neg number
mov dl,'-'
mov ah,02h
int 21h
mov bh,0
mov bl,string[1]
dec bx
mov res[bx],'$'
mov cx,10
mov ax,number
jmp lop
ispositive:
mov bh,0
mov bl,string[1]
mov res[bx],'$'
mov cx,10
mov ax,number
jmp lop
lop:
and ax,ax
jz print
mov dx,0
div cx
add dl,30h
dec bx
mov res[bx],dl
jmp lop
print:
lea dx,res
add dx,bx
mov ah,09h
int 21h
mov dx,0ah ;将光标移到下一行的开始处
mov ah,02h
int 21h
jmp start
mov ah,4ch
int 21h
code ends
end start
二、更详细的解释
assume cs:code,ds:data
data segment
string db 20 ;用于定义一个缓冲区,这一行说明预先申请的最大空间为20个字节
db ? ;string读入几个字符,则这个地方就自动填充为几
db 20 dup(0) ;申请20个字节的空间,并填充
number dw ? ;用于保存结果,将字符串对应的值保存在寄存器中
res db 20 dup(0) ;用寄存器的值转化成的字符串存放的位置
data ends
code segment
start:
mov ax,data;关联data和ds
mov ds,ax
lea dx,string ;输入字符串
mov ah,0ah
int 21h
mov dx,0ah ;将光标移到下一行的开始处
mov ah,02h
int 21h
mov al,string+1 ;在合适的位置添加'$'符号
add al,2
mov ah,0
mov si,ax
mov string[si],'$'
cmp string[2],'-' ;判断是正数还是负数,并跳转
jnz positive
jz negative
positive:
mov dx,0
mov cl,string[1];初始化cx的值,用于统计字符串的长度
mov ch,0
dec cx ;cx--,因为对于整数 XYZ,可以转化为 (x*10+y)*10+z,故而只需要 *10两次
mov di,2
mov bx,0
and cx,cx
jz processlast
s0:
mov ax,10;一个乘数
sub string[di],30h
push dx;将dx的值保护起来,因为后面有 add dx,bx ,dx的值有所改变,故而需要保护
mov bh,0 ;8位寄存器的值赋给16位寄存器
mov bl,string[di]
add dx,bx
mul dx ;一定是16位的乘法,因为中间结果有可能超过8位的储存范围,所以中间过程要用16位存储
pop dx
mov dx,ax
inc di
loop s0
processlast:
sub string[di],30h
mov bl,string[di]
mov bh,0
add dx,bx;dx用于存储中间结果
jmp process ;跳转到下一个处理过程
negative:
mov dx,0
mov cl,string[1]
mov ch,0
sub cx,2
mov di,3
mov bx,0
and cx,cx
jz processlast1
s1:
mov ax,10
sub string[di],30h
push dx;将dx的值保护起来
mov bh,0
mov bl,string[di]
add dx,bx
mul dx ;一定的,因为中间结果有可能超过8位的储存范围
pop dx
mov dx,ax
inc di
loop s1
processlast1:
sub string[di],30h
mov bl,string[di]
mov bh,0
add dx,bx
neg dx
jmp proces;跳转到下一个处理过程
process:;
;参考
;#汇编语言__将一个带符号数以十进制的形式显示
;(https://www.jianshu.com/p/da1b4cedb384)
mov number,dx
shl dx,1;判断是正数还是负数
jnc ispositive
jc isnegative
isnegative:
neg number
mov dl,'-'
mov ah,02h
int 21h
mov bh,0
mov bl,string[1]
dec bx
mov res[bx],'$'
mov cx,10
mov ax,number
jmp lop
ispositive:
mov bh,0
mov bl,string[1]
mov res[bx],'$'
mov cx,10
mov ax,number
jmp lop
lop:
and ax,ax
jz print
mov dx,0
div cx
add dl,30h
dec bx
mov res[bx],dl
jmp lop
print:
lea dx,res
add dx,bx
mov ah,09h
int 21h
mov dx,0ah ;将光标移到下一行的开始处
mov ah,02h
int 21h
jmp start
mov ah,4ch
int 21h
code ends
end start