2015-03-19 100 views
0

我不确定如何将用户输入数据实际存储到寄存器。我想提示用户输入一个带符号的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 

任何特别突出我做错了什么?

+0

您必须将该数字捕获为一串字符,然后使用您自己的转换过程将其转换为数字。 – 2015-03-19 14:41:02

+0

如果显示BX,则只会看到二进制字符。为了显示bx的内容,你必须将其转换为字符串。要显示[BX],你必须把它指向一个字符串。 – 2015-03-19 14:49:40

回答

1

您构建代码的方式,您希望使用01中断,该中断读取并返回单个字符,而不是0A,它将行读入您提供的缓冲区中。

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

jmp endwhile会无条件跳到最后,所以应该使用je endwhile,只有在值相等的情况下才会跳转。 此外,你应该这样做,然后再尝试将al的结果累积到bx,因为其他方面你会在你的数字中包含回车符号。最后记住读入的所有数字很可能是ASCII,所以字符'0'将是48,'1'将是49等等,所以在使用它们作为整数之前,你必须先将48除去。

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

总体而言,为了做你想做的事,需要做大量的重写工作。除非这是为了学习目的,否则我会坚持使用标准的c库方法进行I/O,并使用64位x86而不是16位。

2

要将用户输入数据存储到寄存器中,必须将数据捕获为一串字符,然后创建自己的过程以将字符串转换为数字,最后将结果存储在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更容易)。

,使其与有符号数工作,只是检查字符串的第一个字符为“ - ”(减号),在这种情况下,转换的数量,而不该字符,并且在转换后(后string2number)你乘以-1。对于这两种情况,您最好创建另一个string2number并将其命名为string2numberSigned,它是相同的,但它将循环停止在1,而不是零(以避免将“ - ”转换为数字)。

希望这可以帮助你。