私は学んだ約2's Complement
と署名されていないと署名されたint。だから私は、負の数が2's complement
ウェイに格納されていることを知っている限り、私の知識をテストすることにしました。そのため、加減算には異なるアルゴリズムや回路がないでしょう。私はアセンブリでは、符号なしint作業に負数をどのように割り当てますか?
int main()
{
int a = -1 ;
unsigned int b = - 1 ;
printf("%d %u \n %d %u" , a ,a , b, b);
}
を書く場合
は今、出力が-1 4294967295 -1 4294967295
されるようになります。さて、私はビットパターンと様々なものを見て、次に、2の補数のが11111111 11111111 11111111 11111111
であることを認識したので、%dを使って解釈すると、-1
となりますが、%u
を使って解釈すると、したがって、4294967295
となります。私は、コードの組み立てが今ここに-1
が符号なしと署名の両方倍レジスタに移動され
.LC0:
.string "%d %u \n %d %u"
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], -1
mov DWORD PTR [rbp-8], -1
mov esi, DWORD PTR [rbp-8]
mov ecx, DWORD PTR [rbp-8]
mov edx, DWORD PTR [rbp-4]
mov eax, DWORD PTR [rbp-4]
mov r8d, esi
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
leave
ret
でチェック。私は再解釈が重要であることを知りたいのですが、なぜunsigned
とsigned
の2種類があるのですか?printf
のフォーマット文字列%d
と%u
が重要ですか?
さらに、符号なし整数に負の数を代入すると、実際に何が起こるのですか(私は初期化子がint
からにこの値を変換することを学びましたが)アセンブリコードでこのようなことは見ませんでした。だから本当に何が起こるのですか?
そして、機械はそれが何をしなければならないかをどうやって知っていますか?そうでなければ、負の符号を見て2's complement
を実行しますか?
私はほとんどすべての質問と答えを読んだことがあります。この質問は重複していると思うかもしれませんが、満足できる解決策を見つけることができませんでした。
*「それは2の補数を行う必要があるときどのようにマシンが知っているんやないときは」* - 私はこのことを理解していない - すべてはプログラミングにおけるバイナリであることにダウンしています。マシン命令は、上位レベルの構造体である 'signed'や' unsigned'を気にしません。 – UnholySheep
@UnholySheep私が意味するのは、署名付きのint = -1を書くとき、それは2の補数として格納されるので、このように格納されているかどうかにかかわらずすべての負の数は同じですか? –
C言語の場合、負数は3つの表現の1つになる可能性があります。したがって、必ずしも2の補数である必要はありません。 printf形式も入力と一致する必要があります。そうしないとプログラムが作成されません。現行のC標準では、符号付きの型を符号なしの型に変換したり、符号なしの型から符号付きの型に変換したりしても、2の補数の計算機のビット表現は変更されません。マシンは、変数がレジスタに入っているときに、変数の署名について実際にはわかりません。コンパイラが知っているので、プログラムが知っているので、それで十分です。 – user3528438