:ハードウェアベースまたはカーネル内のどこかだろうどのようにして、コンピュータはASCII文字列を符号付きまたは符号なしの数値に変換しますか?私が入力した場合たとえば
1010
:どのようなメカニズムを介して
-6
をそれがになっていますか?
:ハードウェアベースまたはカーネル内のどこかだろうどのようにして、コンピュータはASCII文字列を符号付きまたは符号なしの数値に変換しますか?私が入力した場合たとえば
1010
:どのようなメカニズムを介して
-6
をそれがになっていますか?
ハードウェアベースでも、カーネルのどこかに存在しますか?
通常はありません。
LinuxのようなメインストリームOSのカーネルは通常、テキストのバイトをユーザー空間に渡します。
したがって、ユーザー空間プログラムは文字列、つまり一連の文字を取得します。 (単純な場合、例えばUTF-8のASCIIサブセットの場合、各文字は1バイトである。)プログラムは通常、文字のシーケンス(数字のASCIIコードを表す)を2進整数に変換するためにatoi()
のような関数を使用する。多くのプログラムが整数を表す文字列を扱う必要があるので、これは標準的なライブラリ関数ですが、それは他のどのようなソフトウェア関数でもあります。
単純な実装は、このC++ソースはそれを実装する複数のasm命令にコンパイルされるだろう
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.
のようなループを持っているでしょう。オプションの-
を否定処理することも別の指示です。通常、ある種のneg
命令、またはゼロから減算する方法があり、2の補数の逆関数を得ることができます。 (2の補数ハードウェアを仮定)。
これは、命令/クロックサイクルごとに多くの作業を行う魅力的な命令を使用することで、スピードアップできます。例えば、x86では、数字の複数桁の文字列を、少数のSIMD命令でバイナリ整数に変換できますが、それでもやはり乗算命令と加算命令を使用しています。 pmaddwd
をうまく使用するには、プレース・バリューのベクトルを乗算して水平に加算するには、How to implement atoi using SIMD?を参照してください。またFastest way to get IPv4 address from stringは、packed-compareでできることのすばらしい例であり、その比較結果に基づいてテーブルからpshufb
シャッフルコントロールベクトルを検索します。
数字を入力として読み取るscanf("%d", &num)
のような関数は、ユーザー空間で実装されますが、フードの下ではread()
のようなシステムコールを使用してデータを取得します。 (C stdioの入力バッファが空だった場合。)
いくつかの「おもちゃ」/教育システムMARSとSPIM MIPSのシミュレータを取得またはプリント整数(入力または整数になりますシステムコールを持っているように登録)。その場合、カーネルはソフトウェアでそれを行います。
また、実際にはカーネルはまったくなく、syscall
命令はエミュレータ/シミュレータの入出力機能にエスケープするので、この仮想シミュレートされたマシン内で実行されるソフトウェアのPOVから、実際には整数変換のハードウェアサポートです。しかし、実際のハードウェアは、マイクロコードや実際のハードウェアではなく、少なくとも主流のアーキテクチャではありません。
なぜ「1010」になるのでしょうか? – melpomene
1010はバイナリで-6です。 –
おそらく4ビット幅の2の補数ですが、それを誰が使用しますか? – melpomene