Linux 为什么递增对大数字的作用与对单个数字的作用不同?
今天刚开始学习基本汇编代码,我正在尝试将用户输入数增加1。当数字大于一位数时,我会得到奇怪的结果。有什么区别吗?问题在于,您的输入被视为数字,而不是字符串。当您收到输入(字符串)时,您会得到一个(ASCII)字符串作为返回值。将第一个字符(数字)增加Linux 为什么递增对大数字的作用与对单个数字的作用不同?,linux,assembly,x86,nasm,increment,Linux,Assembly,X86,Nasm,Increment,今天刚开始学习基本汇编代码,我正在尝试将用户输入数增加1。当数字大于一位数时,我会得到奇怪的结果。有什么区别吗?问题在于,您的输入被视为数字,而不是字符串。当您收到输入(字符串)时,您会得到一个(ASCII)字符串作为返回值。将第一个字符(数字)增加addeax,增量(压缩)确实有效,因为AL(eax的最低字节)中包含的[num]的第一个ASCII字符值增加了一个。这是因为0的ASCII值为48,而9的ASCII值为57 如果您认为您增加了这些“数字”,那么实际上您会增加它们的ASCII值,这在
addeax,增量(压缩)确实有效,因为AL
(eax的最低字节)中包含的[num]
的第一个ASCII字符值增加了一个。这是因为0
的ASCII值为48,而9
的ASCII值为57
如果您认为您增加了这些“数字”,那么实际上您会增加它们的ASCII值,这在达到一位数限制(0-9)之前效果良好。将9
增加1将导致:
而不是10
,正如您可能预期的那样,因为9
的ASCII值为57,再加上1将导致58,这是:
的ASCII值
因此,在使用整数运算之前,您必须“规范化”您的“数字”。将它们从ASCII字符串转换为整数值
幸运的是,其他人在您之前已经这样做了,并将这些方法优化到了实际的最大程度。查找并搜索atoi
(ASCII到整数)和itoa
(整数到ASCII)。然后围绕你的算术运算
section .bss
num1 resb 4
result resb 4
section .data
SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
INCREMENT equ 1
msg1 db 'Please enter an integer here:',0xA
len1 EQU $- msg1
msg2 db 'Your integer after being incremented is:',0xA
len2 EQU $- msg2
section .text
global _start:
_start:
mov eax, SYS_WRITE ; Prompting user to enter a number.
mov ebx, STDOUT
mov ecx, msg1
mov edx, len1
int 0x80
mov eax, SYS_READ ; Reading users number.
mov ebx, STDOUT
mov ecx, num1
mov edx, 4
int 0x80
mov eax, SYS_WRITE ; Writing second message.
mov ebx, STDOUT
mov ecx, msg2
mov edx, len2
int 0x80
mov eax, [num1] ; incrementing the user's number.
mov ebx, INCREMENT
add eax, ebx
mov [result], eax
mov eax, SYS_WRITE ; Printing out incremented number.
mov ebx, STDOUT
mov ecx, result
mov edx, 4
int 0x80
有了这些函数。问题在于,您将输入视为数字,而不是字符串。当您收到输入(字符串)时,您会得到一个(ASCII)字符串作为返回值。将第一个字符(数字)增加addeax,增量(压缩)确实有效,因为AL
(eax的最低字节)中包含的[num]
的第一个ASCII字符值增加了一个。这是因为0
的ASCII值为48,而9
的ASCII值为57
如果您认为您增加了这些“数字”,那么实际上您会增加它们的ASCII值,这在达到一位数限制(0-9)之前效果良好。将9
增加1将导致:
而不是10
,正如您可能预期的那样,因为9
的ASCII值为57,再加上1将导致58,这是:
的ASCII值
因此,在使用整数运算之前,您必须“规范化”您的“数字”。将它们从ASCII字符串转换为整数值
幸运的是,其他人在您之前已经这样做了,并将这些方法优化到了实际的最大程度。查找并搜索atoi
(ASCII到整数)和itoa
(整数到ASCII)。然后围绕你的算术运算
section .bss
num1 resb 4
result resb 4
section .data
SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
INCREMENT equ 1
msg1 db 'Please enter an integer here:',0xA
len1 EQU $- msg1
msg2 db 'Your integer after being incremented is:',0xA
len2 EQU $- msg2
section .text
global _start:
_start:
mov eax, SYS_WRITE ; Prompting user to enter a number.
mov ebx, STDOUT
mov ecx, msg1
mov edx, len1
int 0x80
mov eax, SYS_READ ; Reading users number.
mov ebx, STDOUT
mov ecx, num1
mov edx, 4
int 0x80
mov eax, SYS_WRITE ; Writing second message.
mov ebx, STDOUT
mov ecx, msg2
mov edx, len2
int 0x80
mov eax, [num1] ; incrementing the user's number.
mov ebx, INCREMENT
add eax, ebx
mov [result], eax
mov eax, SYS_WRITE ; Printing out incremented number.
mov ebx, STDOUT
mov ecx, result
mov edx, 4
int 0x80
有了这些功能。您是否知道关于此主题的任何初学者友好资源?不过我现在明白我的错误了。非常感谢。只是不太确定如何实现这些atoi和itoa函数的语法。@Nick M:这类问题已经被问了很多次了,但我还没有找到一个简单的答案。但基本原理很简单:atoi从每个字节减去30h,然后将每个字节与其基数10相乘(1,101001000,…),itoa将该值除以10,直到余数为零。然而,有许多实现。例如,包含这两个主题。您可能知道关于此主题的任何初学者友好资源?不过我现在明白我的错误了。非常感谢。只是不太确定如何实现这些atoi和itoa函数的语法。@Nick M:这类问题已经被问了很多次了,但我还没有找到一个简单的答案。但基本原理很简单:atoi从每个字节减去30h,然后将每个字节与其基数10相乘(1,101001000,…),itoa将该值除以10,直到余数为零。然而,有许多实现。例如,这两项都包括在内。