設定されている2進数のビット数を数えたい。たとえば、ユーザーは2進数で01100001である番号97を入力します。プログラムは、MIPSISAを使用して3ビットが設定されていることを示します。
これはCで実現できますが、アセンブリコードを使用して実現する方法がわかりません。
設定されている2進数のビット数を数えたい。たとえば、ユーザーは2進数で01100001である番号97を入力します。プログラムは、MIPSISAを使用して3ビットが設定されていることを示します。
これはCで実現できますが、アセンブリコードを使用して実現する方法がわかりません。
あなたが探しているものは、しばしば人口数(popcount)と呼ばれます。
Bit Twiddling HacksにはいくつかのC実装があります(そのうちのいくつかは恐ろしく賢いです)。Cに精通している場合は、式を分解した後、各アプローチでMIPSアセンブリに適切に変換する必要があります。
入力ドメインが小さい場合(たとえば、0〜255)、いつでもルックアップテーブルを実行し、入力をオフセットとして使用して、ポップカウントを直接フェッチできます。
これは宿題のように聞こえるので、MIPS コードを示すつもりはありませんが、アルゴリズム (C で記述) は次のとおりです。MIPS に変換するのは簡単です。
int bits(unsigned int number)
{
// clear the accumulator
int accumulator = 0;
// loop until our number is reduced to 0
while (number != 0)
{
// add the LSB (rightmost bit) to our accumulator
accumulator += number & 1;
// shift the number one bit to the right so that a new
// bit is in the LSB slot
number >>= 1;
}
return accumulator;
}
クリスが与えたリンクは、ビットカウントのためのいくつかの良い方法を提供します。この方法をお勧めします。これは、非常に高速でループを必要とせず、ビット単位の操作のみであるため、アセンブリで実行する方が簡単です。
アセンブリコードを取得するもう1つの方法は、Cでコードを作成し、コンパイルしてから、出力アセンブリを確認することです(ほとんどのコンパイルでは、アセンブリファイル出力を生成できます(gccの場合は-Sですが、-O0を使用して最適化を無効にしてください。コードを理解しやすくする)、または分解されたバイナリファイルを表示できるようにする)。それはあなたを正しい方向に向けるべきです。
逸話として、私は32ビット整数のビットをカウントする最も速い方法のためにPowerPC(MIPSではなく、私は知っています...)でしばらく前にいくつかのテストを行いました。私がリンクした方法は、バイトサイズのルックアップテーブルを実行して4回アドレス指定するまで、他のすべての方法よりもはるかに優れていました。ALUは、キャッシュを参照するよりも遅いように思われます(アルゴリズムを介して約100万の数値を実行します)。
基本的な 32 ビット asm のループで簡単です。print_eax が楽しいと仮定すると、これは素朴な方法だと思います。
始める:
mov ebx、97d
ムーブecx、32d
xor eax、eax
蓄積:
ロール ebx,1
jnc 続ける
インクルーシブ
継続する:
ループ累積
print_eax を呼び出す