如何将用户输入的整数保存到寄存器

How to save user-input integer to a register

我不确定如何将用户输入数据实际存储到寄存器中。我想提示用户输入一个带符号的 base-10 整数,然后将该整数存储到 bx 寄存器中。据我所知,我所拥有的似乎并没有实际存储任何数据:

;get user input

   mov   ah, 0Ah
   int   21h


while:
    mov   bx, ax        ;save char to bx
    cmp   ax, 13        ;is char = carriage return?
    jmp   endwhile      ;if so, we're done
    int   21h           ;get another char
    loop  while
endwhile:
    ret                 ;end loop

;print data stored in bx to console

    mov   ah, 09
    mov   dx, [bx]
    int   21h

有什么特别突出的地方是我做错了吗?

您构建代码的方式,您想使用 01 中断,它读取 returns 单个字符,而不是 0A,它将行读入您给它的缓冲区.

mov bx, ax 将覆盖 bx 中的值,因此如果您有 119,则只会存储 9。相反,您应该将 bx 乘以 10,然后将值加到 al.

jmp endwhile 将无条件跳转到 endwhile,因此您应该使用 je endwhile ,它只会在值相等时跳转。 此外,您应该在尝试将 al 的结果累加到 bx 之前执行此操作,否则您将在读入的数字中包含回车 return。最后请记住,读入的所有数字很可能是在 ASCII 中,因此字符“0”将是 48,“1”将是 49,等等。因此在将它们用作整数之前必须减去 48。

mov dx, [bx] 将加载数据到 ds:bx 指向的地址,在这种情况下这是没有意义的。相反,您必须分配一个内存区域,将您的数字转换回字符串,然后给出该区域的地址。这与读取数字的工作量大致相同。

总体而言,需要进行大量重写才能完成您想要的操作。除非这是出于学习目的,否则我会坚持使用 i/o 的标准 c 库方法并使用 64 位 x86 而不是 16 位。

要将用户输入的数据存储到寄存器中,您必须将数据捕获为字符串,然后创建自己的程序将字符串转换为数字,最后将结果存储在 BX 寄存器中。

下一个程序抓取一个最大4位的无符号数,转换成数字存入BX,里面有很多注释帮助你理解,是用EMU8086编译器制作的(复制粘贴运行) :

.stack 100h
;------------------------------------------
.data
;------------------------------------------
msj1   db 'Enter a number: $'
string db 5 ;MAX NUMBER OF CHARACTERS ALLOWED (4).
       db ? ;NUMBER OF CHARACTERS ENTERED BY USER.
       db 5 dup (?) ;CHARACTERS ENTERED BY USER. 
msj2   db 13,10,'Number has been converted',13,10,13,10,'$'
;------------------------------------------
.code          
;INITIALIZE DATA SEGMENT.
  mov  ax, @data
  mov  ds, ax
;------------------------------------------        
;DISPLAY MESSAGE.
  mov  ah, 9
  mov  dx, offset msj1
  int  21h
;------------------------------------------
;CAPTURE CHARACTERS (THE NUMBER).
  mov  ah, 0Ah
  mov  dx, offset string
  int  21h
;------------------------------------------
  call string2number
;------------------------------------------        
;DISPLAY MESSAGE.
  mov  ah, 9
  mov  dx, offset msj2
  int  21h
;------------------------------------------
;STOP UNTIL USER PRESS ANY KEY.
  mov  ah,7
  int  21h
;------------------------------------------
;FINISH THE PROGRAM PROPERLY.
  mov  ax, 4c00h
  int  21h           
;------------------------------------------
;CONVERT STRING TO NUMBER IN BX.
proc string2number         
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
  mov  si, offset string + 1 ;NUMBER OF CHARACTERS ENTERED.
  mov  cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.                                         
  mov  ch, 0 ;CLEAR CH, NOW CX==CL.
  add  si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
  mov  bx, 0
  mov  bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:         
;CONVERT CHARACTER.                    
  mov  al, [ si ] ;CHARACTER TO PROCESS.
  sub  al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
  mov  ah, 0 ;CLEAR AH, NOW AX==AL.
  mul  bp ;AX*BP = DX:AX.
  add  bx,ax ;ADD RESULT TO BX. 
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
  mov  ax, bp
  mov  bp, 10
  mul  bp ;AX*10 = DX:AX.
  mov  bp, ax ;NEW MULTIPLE OF 10.  
;CHECK IF WE HAVE FINISHED.
  dec  si ;NEXT DIGIT TO PROCESS.
  loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.
  ret 
endp    

如果你改变了BX并想稍后显示它,你将不得不创建自己的程序来将数字转换为字符串(该算法比string2number更容易)。

为了使其适用于带符号的数字,只需检查字符串的第一个字符是否为“-”(减号),在这种情况下,转换没有该字符的数字,并在转换后([=21 之后) =]string2number) 你乘以-1。对于这两种情况,您最好创建另一个 string2number 并将其命名为 string2numberSigned,它是相同的,但它在 1 处停止循环,而不是在零处停止循环(以避免将“-”转换为数字)。

希望对您有所帮助。