MS-DOSの悪い時代に、レジスタに高ニブルと低ニブルを設定し、Interuptxxを実行することによって特定のOS機能が制御されていたことを思い出してください。たとえば、Int21は多くのファイル関数にアクセスしました。あなたはドライブ番号として高いニブルを設定します-誰が15以上のドライブを持っていますか?そのドライブで要求された機能としての低ニブルなど。
これは、MS-DOSシステムコールを実行するようにレジスタを設定するために説明するようにpackを使用する古いCPANコードです。
Blech !!! 私はMS-DOSをまったく見逃していません...
- 編集
具体的なソースコードは次のとおりです。DOS用のPerl5.00402をここからダウンロードし、解凍し、
ファイルOpcode.pmおよびOpcode.plには、次の使用法が記載unpack("h*",$_[0]);
されています。
sub opset_to_hex ($) {
return "(invalid opset)" unless verify_opset($_[0]);
unpack("h*",$_[0]);
}
私はコードを最後までたどりませんでしたが、私の疑いは、これがMS-DOSシステムコールから情報を回復することであるということです...
Perl 5.8-8のperlportには、ターゲットのエンディアン性に関する次の推奨テストがあります。
さまざまなCPUが、整数と浮動小数点数をさまざまな順序(エンディアンと呼ばれる)と幅(現在最も一般的な32ビットと64ビット)で格納します。これは、プログラムがバイナリ形式で1つのCPUアーキテクチャから別のCPUアーキテクチャに番号を転送しようとするときに影響します。通常、ネットワーク接続を介して「ライブ」であるか、ディスクファイルやテープなどのセカンダリストレージに番号を保存します。
競合する保管注文は、数を完全に混乱させます。リトルエンディアンホスト(Intel、VAX)が0x12345678
(305419896
10進数で)格納する場合、ビッグエンディアンホスト(Motorola、Sparc、PA)はそれを
0x78563412
(2018915346
10進数で)読み取ります。AlphaとMIPSは、次のいずれかになります。デジタル/コンパックが使用/リトルエンディアンモードで使用。SGI / Crayは、それらをビッグエンディアンモードで使用します。ネットワーク(ソケット)接続でこの問題を回避するには、pack
andunpack
形式n
とN
「ネットワーク」順序を使用します。これらはポータブルであることが保証されています。
perl 5.8.5以降では、>
および<
修飾子を使用して、ビッグエンディアンまたはリトルエンディアンのバイトオーダーを強制することもできます。これは、たとえば、符号付き整数または64ビット整数を格納する場合に役立ちます。
次のようなネイティブ形式でパックされたデータ構造を解凍することで、プラットフォームのエンディアンを調べることができます。
print unpack("h*", pack("s2", 1, 2)), "\n";
# '10002000' on e.g. Intel x86 or Alpha 21064 in little-endian mode
# '00100020' on e.g. Motorola 68040
エンディアンアーキテクチャを区別する必要がある場合は、次のように設定された変数のいずれかを使用できます。
$is_big_endian = unpack("h*", pack("s", 1)) =~ /01/;
$is_little_endian = unpack("h*", pack("s", 1)) =~ /^1/;
幅が異なると、エンディアンが等しいプラットフォーム間でも切り捨てが発生する可能性があります。幅が短いプラットフォームでは、数字の上部が失われます。生の2進数の転送または保存を回避する以外に、この問題に対する適切な解決策はありません。
これらの問題は2つの方法で回避できます。数値を生のバイナリではなく常にテキスト形式で転送して保存するか、Data::Dumper
(Perl 5.005以降の標準ディストリビューションに含まれている)やStorable
(perl 5.8以降に含まれている)などのモジュールの使用を検討してください。すべてのデータをテキストとして保持すると、問題が大幅に簡素化されます。
v2147483647
v-stringは、 ( )までしか移植できませ0x7FFFFFFF
ん。これは、EBCDIC、より正確にはUTF-EBCDICが進む距離です。
unpack("h*",...)
より頻繁に使用されているようですpack("h*",...)
。私はそれがPerl5.12で 使用さreturn qq'unpack("F", pack("h*", "$hex"))';
れていることに注意しましたDeparse.pm
IO-Compress
pack("*h",...)
さらに例が必要な場合は、Googleコード検索リストをご覧ください。ご覧pack|unpack("h*"...)
のとおり、かなりまれであり、主にプラットフォームのエンディアンを決定することに関係しています...