目标

  • 设计一个INPUT子程序,使其能够接收用户输入的数字(以字符串的形式),并将数字存储到AX寄存器。
  • 设计一个DECOUT/BINOUT/HEXOUT子程序,使他们能够以十进制/二进制/十六机制的形式将AX中的数字输出到屏幕上。

分析

  • 对于INPUT子程序,我们需要调用DOS功能接收用户输入的字符串,将ASCII码转为数字,再依次乘以10、100…由于CPU执行指令时会占用AX,我们将积的累加和存储在内存变量中,最后一步复制到AX中。
  • 对于DECOUT子程序,我们对AX中的数除以进制数,将余数保存到内存中,循环此过程直至商为0,最后借用si寄存器变址寻址反向输出余数(转换为ASCII码)即可向用户展示AX中的数字。

INPUT

  • 调用DOS的0a号功能接收字符串
data segment
  str db 20h
  num db 0
  content db 20h dup(0)
data ends
...
mov dx,offset str
mov ah,0ah
int 21h
  • 外循环(ASCII码转数字,调用内循环)
data segment
  consequence dw 20h;存放结果
data ends
...
xor ax,ax;用异或清零
mov al,str+1;一共这么多字符,循环的范围是str[2]到str[si+1]
mov si,ax;用si计数

flag:xor ax,ax
mov al,str[si+1]
sub ax,30h;-30h将ascii码转数字
内循环
add consequence,ax
dec si
cmp si,0;si=0的时候不能再跳转了
jnz flag

mov ax,consequence
  • 内循环(将从右向左第n位数转换为n*10^(n-1),已知ax的内容是第(总位数+1-si)位数,其中si每次外循环-1,故乘以10的次数为(总位数-si);我们可以将总位数复制到cur内存变量,每次内循环-1,当cur=si,内循环结束):
data segment
cur dw 0;第几位
data ends
...

xor bx,bx
mov bl,num
mov cur,bx

mul10:cmp si,cur;如果外循环正处于第n位,内循环也处于第n位,不需要再乘以10
jz endd
mov bx,0ah
mul bx;ax*10,结果存放在dx|ax
dec cur
jmp mul10
endd:

DECOUT

  • DECOUT中BX的值可以决定输出的进制
binout proc;将ax的值以二进制显示
xor si,si;利用si寻址

mov bx,2
divv:cwd
div bx;余数在dx
add dl,30h;转位ascii码
mov num[si],dl;
inc si
cmp ax,0;商0即结束
jnz divv;商不为0的时候

mov cx,si
;上面多加了一次si
display: dec si
 mov dl,num[si]
mov ah,02h;调用字符显示
  int 21h
loop display
ret
binout endp