は、シフトを使用する別の解決策ですが、私は「クリーナー」(デビッドの提案のようにきれいではないが)であると考えている:
result := MSB;
result := (result shl 8) or b2; { could use "shl sizeof(b2)" instead of 8 }
result := (result shl 8) or b3;
etc
result := (result shl 8) or b8;
このソリューションは、すべての「魔法」を回避おそらく分かりやすいでしょう。また、MSB..b8(またはb1..b8)がバイトの配列であった場合、上記のコードは簡単に1つのラインループに変換できます。
:
は、コンパイラが上記の値40とを受け入れていない理由として、あなたの質問に答えるために、理由はSHLD命令のインテル命令セット・リファレンスのボリューム2Bからのこの引用可能性が最も高いです
非64ビットモードではデフォルトの64ビット モードです。カウント0〜4のビットのみが使用されます。このマスク カウントがオペランド サイズよりも大きい場合には0と31の間の値へのカウント は、結果は未定義です。
SHL命令の同等の条件がそれほど厳しくないです
8086は、シフト 数をマスクしません。しかし、(インテル 286プロセッサから始まる)他のすべてのIA-32 プロセッサは、このマスキングは で行われる31の最大 数で、その結果、シフト・カウントを 5ビットをマスク行うすべての動作モード( を含みます仮想8086モード)を使用して、 命令の最大実行時間を 減らしてください。
いずれの場合でも、31を超える値は無用(SHLを使用する場合)または未定義(SHLDを使用する場合)のいずれかです。コンパイラはこれを明らかに知っており、潜在的に誤りのあるコードを書くことを妨げている(64ビットモードで)。
実際にこの操作を50億回実行している場合は、
asm
xor eax, eax
or eax, MSB { or b1 depending on how you named the MSB }
shl eax, 8
or eax, b2
shl eax, 8
or eax, b3
shl eax, 8
or eax, b4
mov High32bit, eax
end;
と下位32ビットのダブルワード及びB8スルーB5のための上記動作を繰り返す:非常に簡単になり、インラインアセンブリ。 Delphiが64ビットレジスタや64ビット命令をサポートしているとは思えないので、私はSHLDを使用することを提案しませんでした(私は間違っているかもしれませんが、試したことはありません)。
注: Delphiのバージョンはインラインアセンブリをサポートしません。これは実際の場合とそうでない場合がありますが、本当に必要な場合を除き、インラインアセンブリから離れています。
PS:David Heffernanの解決策が最高の理由があります。私が提示したソリューションでは、すべての命令は前の命令に依存しています(つまり、次の "or"命令を実行する前にeaxを8だけシフトしなければなりません)。 Davidのソリューションは個々のバイトを設定するので、各割り当ては以前の割り当てとは独立しています。これにより、プロセッサは複数の割り当てを並列で実行する可能性があります。マルチコアプロセッサのこの時代では、これは例として与えたアセンブリコードよりもかなり速いという可能性を秘めています。
結果はInt64型ですか?そしてb3も? Int64に型キャストを挿入できますか?Int64(b3)? – Andreas
申し訳ありません。ごめんなさい。私はそれを完全に忘れてしまった。私は私の質問を更新しました。 – Ampere