计算机如何将一串 ASCII 转换为有符号或无符号数字?

How does a computer turn a string of ASCII into a signed or unsigned number?

例如,如果我输入:

-6

通过什么机制变成:

1010

它是基于硬件还是内核中的某个地方?

Would it be hardware based or somewhere in the kernel?

通常没有也没有。

像Linux这样的主流OS内核通常只会将文本字节传递给用户-space。

所以一个用户-space程序得到一个字符串,即一个字符序列。 (在简单的情况下,例如 UTF-8 的 ASCII 子集,每个字符都是一个字节。)程序通常会使用 atoi() 之类的函数将字符序列(表示数字的 ASCII 代码)转换为二进制整数。这是一个标准库函数,因为许多程序需要处理表示整数的字符串,但它就像其他任何软件函数一样。

一个简单的实现会有一个像

这样的循环
int sum = 0;
for (auto d: digits) {   // look at digits in MSB-first order
    sum = 10*sum + d;
}
// the first digit ends up being multiplied by 10 n times
// the 2nd by 10 n-1 times, and so on. Each digit is multiplied by its place value.

此 C++ 源代码将被编译为实现它的多个 asm 指令。通过否定处理可选的 - 也是一个单独的指令。通常有某种 neg 指令,或从零减去的方法,以获得 2 的补码逆。 (假设 2 的补码硬件)。


您可以通过使用每条指令/每个时钟周期执行更多工作的更高级指令来加快速度。例如,在 x86 上,您可以使用一些 SIMD 指令将多位数字串转换为二进制整数,但这仍然只是使用乘法和加法指令。请参阅 for a nice use of pmaddwd to multiply by a vector of place-values and horizontally add. Also 是一个很酷的示例,说明您可以使用打包比较并根据比较结果从 table 中查找 pshufb 洗牌控制向量。

scanf("%d", &num) 这样将输入读取为数字的函数在 user-space 中实现,但在幕后它使用像 read() 这样的系统调用来获取数据。 (如果 C stdio 输入缓冲区为空。)


一些 "toy" / 教学系统,如 MARS 和 SPIM MIPS 模拟器,具有获取或打印整数的系统调用(输入或结果在整数寄存器中)。在那种情况下,是的,内核在软件中完成。

或者根据实现,实际上根本没有内核,syscall 指令转义到仿真器/模拟器的 input/output 函数,所以从软件的 POV 运行在这个虚拟模拟机里面,真的是有整数转换的硬件支持。但是没有真正的硬件在微代码或实际硬件中完成所有事情,至少不是任何主流架构。