如何将用户输入的整数保存到寄存器
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 处停止循环,而不是在零处停止循环(以避免将“-”转换为数字)。
希望对您有所帮助。
我不确定如何将用户输入数据实际存储到寄存器中。我想提示用户输入一个带符号的 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 处停止循环,而不是在零处停止循环(以避免将“-”转换为数字)。
希望对您有所帮助。