2015-03-19 99 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,而不是零(以避免將「 - 」轉換爲數字)。

希望這可以幫助你。