我不确定如何将用户输入数据实际存储到寄存器中。我想提示用户输入一个带符号的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
特别突出我做错了什么?
答案 0 :(得分:2)
要将用户输入数据存储到寄存器,您必须将数据捕获为一串字符,然后创建自己的过程以从字符串转换为数字,最后将结果存储在BX寄存器中。
下一个程序捕获一个最多4位数的无符号数,将其转换为数字并将其存储在BX中,它有很多注释可以帮助您理解,它是用EMU8086编译器制作的(只需复制,粘贴和运行): / p>
.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 <之后) / strong>)你将它乘以-1。对于这两种情况,你最好创建另一个string2number并将其命名为string2numberSigned,它是相同的,但它会将循环停在1而不是零(以避免将“ - ”转换为数字)。
希望这会对你有所帮助。
答案 1 :(得分:1)
您构建代码的方式,您希望使用01中断,它读取并返回单个字符,而不是0A,它将行读入您提供的缓冲区。
mov bx, ax
将覆盖bx
中的值,因此如果您有119,则只会存储9。相反,你应该将bx乘以10,然后在al。
jmp endwhile
将无条件地跳到最后,所以你应该使用je endwhile
,只有当值相等时才会跳转。
另外,在尝试将al的结果累积到bx之前,你应该这样做,因为其他方面你会在你的数字中包含回车符。最后请记住所有读入的数字很可能是ASCII ,所以角色&#39; 0&#39;将是48岁,&#39; 1&#39;将是49等,所以在将它们用作整数之前你必须减去48。
mov dx, [bx]
会将数据加载到ds:bx指向的地址,在这种情况下无意义。相反,您必须分配一个内存区域,将您的号码转换回字符串,然后提供该区域的地址。这与阅读数字的工作大致相同。
总体而言,为了做你想做的事,需要进行大量的重写。除非这是出于学习目的,否则我会坚持使用标准c库方法进行i / o并使用64位x86而不是16位。