ファットバイナリ(またはマルチアーキテクチャバイナリ)は、複数の命令セットに固有のコードで拡張(または「ファット化」)されたコンピュータ実行可能プログラムまたはライブラリであり、複数のプロセッサタイプで実行できます。[1]これにより、通常の1つのアーキテクチャのバイナリファイルよりも大きなファイルが生成され、これが名前の由来です。
通常の実装方法は、各命令セットに対応するマシンコードのバージョンを組み込み、その前にすべてのオペレーティングシステムと互換性のあるコードを含む単一のエントリポイントを配置し、適切なセクションへのジャンプを実行します。別の実装では、異なる実行ファイルを異なるフォークに格納し、それぞれにオペレーティングシステムが直接使用する独自のエントリポイントを持たせます。
ファットバイナリの使用はオペレーティングシステムソフトウェアでは一般的ではありません。同じ問題を解決するには、インストール時にアーキテクチャ固有のバイナリを選択するインストーラプログラムの使用( Androidの複数のAPKなど)、実行時にアーキテクチャ固有のバイナリを選択する( Plan 9のユニオンディレクトリなど)など、いくつかの代替手段があります。GNUstepのファットバンドルなど)、[2] [3]ソースコード形式でソフトウェアを配布し、その場でコンパイルしたり、仮想マシン( Javaなど)を使用してジャストインタイムコンパイルを行う。
1988年、アポロコンピュータのDomain/OS SR10.1は、モトローラ680x0とアポロPRISM実行ファイルのバイナリをバンドルした新しいファイルタイプ「cmpexe」(複合実行ファイル)を導入しました。[4]
1994年に始まったApple Macintoshの68KマイクロプロセッサからPowerPCマイクロプロセッサへの移行は、ファットバイナリ方式によってスムーズに進みました。旧プラットフォーム向けの多くのアプリケーションは、進化するエミュレーション方式によって新プラットフォーム上で透過的に動作しましたが、エミュレートされたコードは一般的にネイティブコードよりも動作が遅くなりました。「ファットバイナリ」としてリリースされたアプリケーションは、より多くのストレージ容量を必要としましたが、どちらのプラットフォームでもフルスピードで動作しました。これは、同じプログラムの68Kコンパイル版とPowerPCコンパイル版の両方を実行ファイルにパッケージ化することで実現されました。 [5] [6]旧68Kコード(CFM-68Kまたはクラシック68K)は引き続きリソースフォークに格納され、新PowerPCコードはPEF形式でデータフォークに格納されました。[7] [8] [9]
ファットバイナリはPowerPCや68kのみをサポートするプログラムよりもサイズが大きいため、不要なバージョンを削除するユーティリティが数多く開発されました。[5] [6] 80MBのハードドライブが一般的だった小型ハードドライブの時代には、プログラムコードがドライブ全体の使用量の大きな割合を占めていたため、これらのユーティリティが役に立つこともありました。ファットバイナリから不要なメンバーを削除すると、ハードドライブ上のスペースを大幅に節約できます。
ファットバイナリは、 NeXTのNeXTSTEP / OPENSTEPオペレーティングシステムの機能であり、NeXTSTEP 3.1から導入されました。NeXTSTEPでは「マルチアーキテクチャバイナリ」と呼ばれていました。マルチアーキテクチャバイナリは当初、NeXTのMotorola 68kベースのハードウェアと、NeXTSTEPが動作するIntel IA-32ベースのPCの両方で実行できるようにソフトウェアをコンパイルすることを目的としており、両プラットフォームに対応した単一のバイナリファイルが用意されていました。[10]その後、OPENSTEPアプリケーションをPCやOPENSTEPがサポートする様々なRISCプラットフォームで実行できるようにするためにも使用されました。マルチアーキテクチャバイナリファイルは特殊なアーカイブ形式で、1つのファイルに、マルチアーキテクチャバイナリがサポートするアーキテクチャごとに1つ以上のMach-Oサブファイルが格納されます。すべてのマルチアーキテクチャバイナリは、2つの符号なし整数を含む構造体()で始まります。最初の整数(「マジック」)は、このファイルがファットバイナリであることを識別するためのマジックナンバーstruct fat_headerとして使用されます。 2番目の整数(nfat_arch)は、アーカイブに含まれるMach-Oファイルの数(異なるアーキテクチャにおける同一プログラムのインスタンス数)を定義します。このヘッダーの後には、nfat_arch個の fat_arch 構造体()が続きます。この構造体は、ファイルの先頭からのオフセット、アラインメント、サイズ、そしてアーカイブ内のMach-Oバイナリが対象とするCPUタイプとサブタイプを定義します。
struct fat_arch
開発ツールに同梱されていたGNUコンパイラコレクションのバージョンは、NeXTStepが実行可能な様々なアーキテクチャ向けにソースコードをクロスコンパイルすることができました。例えば、複数の「-arch」オプション(アーキテクチャを引数として指定)を使用して、ターゲットアーキテクチャを選択することができました。これは、異なるアーキテクチャで動作するNeXTStep用プログラムを配布する便利な方法でした。
異なるターゲット オブジェクト ファイルを使用してライブラリを作成することも可能でした (たとえば、NeXTStep のlibtoolを使用)。
Apple Computerは1996年にNeXTを買収し、OPENSTEPのコードの開発を継続した。Mach-OはAppleの無料のDarwinオペレーティングシステム(2000年)とAppleのMac OS X(2001年)のネイティブオブジェクトファイル形式となり、NeXTのマルチアーキテクチャバイナリはオペレーティングシステムで引き続きサポートされた。Mac OS Xでは、マルチアーキテクチャバイナリを使用して、アーキテクチャの複数のバリアントをサポートできる。たとえば、PowerPC G3、PowerPC G4、PowerPC 970世代のプロセッサに最適化された32ビットコードの異なるバージョンを持つことができる。また、32ビットと64ビットのPowerPC、PowerPCとx86、x86-64とARM64など、複数のアーキテクチャをサポートすることもできます。[ 11]

2005年、AppleはPowerPCプロセッサからIntel x86プロセッサへの新たな移行を発表しました。Appleは、マルチアーキテクチャバイナリ形式の実行ファイルを使用することで、PowerPCとx86の両方をネイティブにサポートする新しいアプリケーションの配布を推進しました。[12] Appleはこのようなプログラムを「ユニバーサルアプリケーション」と呼び、ファイル形式を「ユニバーサルバイナリ」と呼んでいます。これは、この新しい移行を以前の移行やマルチアーキテクチャバイナリ形式の他の用途と区別するためと思われます。
ユニバーサルバイナリ形式は、既存のネイティブ PowerPC アプリケーションのフォワードマイグレーションには必要ありませんでした。2006 年から 2011 年にかけて、Apple は、この役割を果たすために、PowerPC (PPC) から x86 への動的バイナリトランスレータであるRosetta を提供しました。しかし、Rosetta はパフォーマンスのオーバーヘッドがかなり高かったため、開発者はユニバーサルバイナリを使用して PPC と Intel バイナリの両方を提供するように推奨されました。ユニバーサルバイナリの明らかなコストは、インストールされるすべての実行可能ファイルが大きくなることですが、PPC のリリース以降の数年で、ハードドライブの容量は実行可能ファイルのサイズを大幅に上回っています。ユニバーサルバイナリは、同じアプリケーションの単一プラットフォームバージョンの 2 倍のサイズになる可能性がありますが、空き領域リソースは一般にコードサイズをはるかに上回るため、これは小さな問題になります。実際、プログラムリソースを複製せずに共有できるため、ユニバーサルバイナリアプリケーションは、2 つの単一アーキテクチャアプリケーションよりも小さくなることがよくあります。すべてのアーキテクチャが必要でない場合は、lipoおよびdittoコマンドライン アプリケーションを使用して、マルチアーキテクチャ バイナリ イメージからバージョンを削除し、いわゆる「シン バイナリ」を作成できます。
さらに、マルチアーキテクチャ バイナリ実行可能ファイルには、PowerPC および x86 の 32 ビット版と 64 ビット版の両方のコードを含めることができるため、アプリケーションは 32 ビット プロセッサをサポートする形式で出荷できますが、64 ビット プロセッサで実行する場合は、より大きなアドレス空間と幅広いデータ パスを利用できます。
Xcode開発環境のバージョン2.1から3.2(Mac OS X 10.4からMac OS X 10.6で動作)では、アプリケーションをIntelアーキテクチャとPowerPCアーキテクチャの両方に対応させるためのユーティリティがAppleによって提供されていました。ユニバーサルバイナリには、最終的に最大4つのバージョンの実行コード(32ビットPowerPC、32ビットx86、64ビットPowerPC、64ビットx86)が含まれるようになりました。しかし、PowerPCのサポートはXcode 4.0から削除されたため、Mac OS X 10.7以降で動作する開発者は利用できません。
2020年、AppleはIntel x86プロセッサからApple Silicon(ARM64アーキテクチャ)への移行を発表しました。移行をスムーズにするため、AppleはUniversal 2バイナリ形式のサポートを追加しました。Universal 2バイナリファイルは、x86-64とARM64の両方の実行可能コードを含むマルチアーキテクチャバイナリファイルであり、64ビットIntel Siliconと64ビットApple Siliconの両方でネイティブに実行できます。さらに、Appleはx86からArm64への命令セットの動的バイナリ変換であるRosetta 2を導入し、Universalバイナリバリアントを持たないアプリケーションも実行できるようにしました。
2006年、AppleはPowerPCからIntel CPUに切り替え、Open FirmwareをEFIに置き換えました。しかし、2008年までに、一部のMacは32ビットEFIを使用し、一部のMacは64ビットEFIを使用するようになりました。そのため、AppleはEFI仕様を拡張し、32ビットと64ビットの両方のEFIバイナリを含む「ファット」バイナリを導入しました。[13]
Intel 8080 (およびZilog Z80 ) プロセッサ ファミリ用のCP/M-80、MP/M-80、Concurrent CP/M、CP/M Plus、Personal CP/M-80、SCPおよびMSX-DOS実行ファイルは、 Intel 8086バイナリ用のDOS互換オペレーティング システムと同じ.COMファイル拡張子を使用します。 [nb 1]どちらの場合も、プログラムはオフセット +100h にロードされ、ファイルの最初のバイトにジャンプして実行されます。[14] [15] 2 つのプロセッサ ファミリのオペコードには互換性がないため、間違ったオペレーティング システムでプログラムを起動しようとすると、不正な予期しない動作が発生します。
これを避けるために、CP/M-80 と DOS プログラムの両方を含み、両方のプラットフォームで正しく解釈される初期コードが先行するファットバイナリを作成する方法がいくつか考案されました。[15]これらの方法では、それぞれ対応する環境向けに構築された 2 つの完全に機能するプログラムを組み合わせるか、間違ったプロセッサで起動された場合にプログラムが正常に終了するようにするスタブを追加します。 これが機能するには、.COM ファイルの最初のいくつかの命令 (ガジェット ヘッダー[16]と呼ばれることもある) が 8086 プロセッサと 8080 プロセッサの両方で有効なコードである必要があり、それによってプロセッサがコード内の異なる場所に分岐することになります。[16] たとえば、Simeon Cran のエミュレータ MyZ80 のユーティリティは、オペコード シーケンスEBh、52h、EBhで始まります。[17] [18] 8086はこれをジャンプ命令とみなし、次の命令をオフセット+154hから読み込みます。一方、8080または互換プロセッサは、そのまま+103hから次の命令を読み込みます。この目的で使用される同様のシーケンスは、EBh、03h、C3hです。[19] [20] John C. ElliottのFATBIN [21] [22] [23]は、CP/M-80とDOSの.COMファイルを1つの実行ファイルに結合するためのユーティリティです。[17] [24]オリジナルのPMsfxの派生版は、美濃喜彦氏のPMarcで作成されたアーカイブを、EBh、18h、2Dh、70h、6Dh、73h、2Dhで始まり、CP/M-80とDOSの両方で自己解凍可能になるように修正し、自己解凍型PMAアーカイブの「-pms-」署名も含め、[25] [17] [24] [18]実行可能なASCIIコードの形式も表現しています。
DOS互換オペレーティングシステムがCP/M-80およびMSX-DOSマシン用の.COMプログラムを誤って実行しないようにする別の方法[15]は、8080コードをC3h, 03h, 01hで開始することです。これはx86プロセッサでは「RET」命令としてデコードされ、プログラムを正常に終了します[注2]。一方、8080プロセッサでは「JP 103h」命令としてデコードされ、プログラム内の次の命令にジャンプします。同様に、SLR SystemsのCP/MアセンブラZ80ASM+は、DOS上で誤って実行するとエラーメッセージを表示します[17]。
CP/M-80 3.0 .COM ファイルの中には、 GENCOMによって1 つ以上のRSXオーバーレイが付加されているものがあります。[26]その場合、ファイルは256 バイト(1ページ)の追加ヘッダーで始まります。これを示すために、ヘッダーの先頭バイトはマジックバイトC9hに設定されています。これは、CP/M 3.0実行可能ローダーがこのタイプの COM ファイルを識別するための署名として機能するだけでなく、8080 互換プロセッサ用の "RET" 命令としても機能し、古いバージョンの CP/M-80 でファイルを実行すると正常に終了します。[注 2]
C9h は、どの x86 プロセッサのプログラムの最初のバイトとしても決して適切ではありません (世代によって意味が異なりますが、[注 3]決して意味のある最初のバイトではありません)。DOS の一部のバージョンの実行可能ローダーは、誤操作を回避するために、 C9hで始まる COM ファイルを拒否します。
同様の重複コードシーケンスは、Z80/ 6502、[17] 、 8086/ 68000 [17]、またはx86/ MIPS / ARMバイナリの組み合わせでも考案されています。[16]
CP/M-86とDOSは、実行ファイルのファイル拡張子を共有していません。[注 1]そのため、通常、実行ファイルを混同することはありません。しかし、初期のDOSバージョンは、アーキテクチャの点でCP/Mと非常に多くの共通点を持っていたため、初期のDOSプログラムの中には、実行コードを含むバイナリを共有するように開発されたものもありました。このようなプログラムとして知られているものの1つにWordStar 3.2xがあります。このプログラムは、 CP/M-86とMS-DOSへの移植において同一のオーバーレイファイルを使用し、[27]実行時にこれらのオペレーティングシステムの異なる呼び出し規約に適応するために、動的に修正されたコードを使用していました。[27]
Digital ResearchのCP/M-86およびDOS用のGSXもバイナリ同一の16ビットドライバを共有しています。[28]
DOSデバイス ドライバ(通常、ファイル拡張子は.SYS ) は、ファイル ヘッダーで始まります。最初の 4 バイトは慣例によりFFFFFFFFhですが、これは必須ではありません。 [29]これは、ドライバがロードされるときにオペレーティング システムによって動的に修正されます(通常、DOS BIOSでCONFIG.SYS内のDEVICEステートメントを実行するときに修正されます)。 DOS は、DEVICE ごとに .COM 拡張子のファイルのロードを拒否せず、FFFFFFFFh をテストしないため、ファイルの最初の 4 バイト (通常は 3 バイトで十分です) 内に埋め込まれた COM プログラムのエントリ ポイントへのジャンプ命令を配置することにより、COM プログラムとデバイス ドライバを同じファイルに組み合わせることができます [30] [29]。[29]埋め込まれたプログラムとデバイス ドライバのセクションでコードまたはデータの共通部分を共有している場合、コードは、.COM スタイルのプログラムとしてオフセット +0100h にロードされ、デバイス ドライバとして +0000h にロードされることを処理する必要があります。[30]「間違った」オフセットでロードされたが、位置独立として設計されていない共有コードの場合、内部アドレスの修正[30]が必要になります。これは、再配置ローダーによってすでに実行されているものと似ていますが、この場合は、ロードされたプログラム自体によって実行する必要があるという点が異なります。これは、自己再配置ドライバーの状況に似ていますが、プログラムはオペレーティングシステムのローダーによってすでにターゲットの場所にロードされています。
DOSでは、慣例により、一部のファイルのファイル拡張子は実際のファイルタイプを反映しません。[nb 4]たとえば、COUNTRY.SYS [31]はDOSデバイスドライバではなく、[nb 5] CONFIG.SYS COUNTRYディレクティブおよびNLSFUNCドライバで使用されるバイナリNLSデータベースファイルです。[31]同様に、PC DOSおよびDR-DOSシステムファイルIBMBIO.COMおよびIBMDOS.COMは、ブートストラップローダーによってロードされる特殊なバイナリイメージであり、COMスタイルのプログラムではありません。[nb 5] DEVICEステートメントを使用してCOUNTRY.SYSをロードしようとしたり、コマンドプロンプトでIBMBIO.COMまたはIBMDOS.COMを実行したりすると、予期しない結果が発生します。[nb 4] [nb 6]
上記と同様の手法を用いることで、これを回避できる場合もあります。例えば、DR-DOS 7.02以降には、Matthias R. Paul氏が開発した安全機能が組み込まれています。[32]これらのファイルが不適切に呼び出された場合、埋め込まれた小さなスタブがファイルのバージョン情報を表示し、正常に終了します。[33] [32] [34] [31]さらに、このメッセージは、外部のNetWare & DR-DOS VERSIONファイル識別ユーティリティが認識する特定の「マジック」パターンに従うように特別に作成されています。[31] [32] [注 7]
同様の保護機能として、ジェイ・セージとジョー・ライトのZシステムタイプ3およびタイプ4の「Z3ENV」プログラム[35] [36]と「Z3TXT」言語オーバーレイファイル[37]の先頭に8080命令C7h (「RST 0」)があり、これらは不適切にロードされた場合、CP/M-80ではクラッシュではなくウォームブートを引き起こすことがあった。 [35] [36] [37] [注2]
これに似た形で、多くの(バイナリ)ファイル形式では、慣例的にファイルの先頭近くに1Ahバイト(ASCII ^Z )が挿入されます。この制御文字は、ファイルが非バイナリモードで開かれた際に「ソフト」ファイル終端(EOF)マーカーとして解釈されます。そのため、多くのオペレーティングシステム(PDP-6モニター[38]、RT-11、VMS、TOPS-10、[39] CP/M、[40] [41] DOS、[42] Windows [43]など)では、ファイルが誤ってコンソールに表示された際に「バイナリガベージ」が表示されるのを防ぎます。

FatELF [44]は、 Linuxやその他のUnix系オペレーティングシステム向けのファットバイナリ実装でした。技術的には、FatELFバイナリは、どのアーキテクチャでどのバイナリを使用するかを示すメタデータを含むELFバイナリを連結したものです。 [45] CPUアーキテクチャの抽象化(バイトオーダー、ワードサイズ、CPU命令セットなど)に加えて、複数のカーネルABIとバージョンをサポートするバイナリという利点があります。
開発者によると、FatELFにはいくつかの使用例がある。[44]
概念実証用のUbuntu 9.04イメージが利用可能である。[47] 2021年現在[アップデート]、FatELFはメインラインLinuxカーネルに統合されていない。[要出典] [48] [49]
Windowsが使用するPortable Executable形式では、コードをプラットフォームに割り当てることはできませんが、アーキテクチャに基づいてディスパッチするローダープログラムを作成することは可能です。これは、ARM版Windowsのデスクトップ版が32ビットx86エミュレーションをサポートしているため、汎用的なマシンコードターゲットとして有用であるためです。Fatpackはこの概念を実証するローダーであり、リソースセクションにパックされた実行ファイルを1つずつ実行しようとする32ビットx86プログラムを含んでいます。[50]
Windows 11 ARM64の開発において、MicrosoftはPortable Executable形式を拡張する新しい方法であるArm64Xを導入しました。[51] Arm64Xバイナリには、x64/Arm64ECとArm64のバイナリそれぞれに含まれるすべてのコンテンツが、ディスク上でより効率的な1つのファイルに統合されています。Visual C++ツールセットは、このようなバイナリの作成をサポートするようにアップグレードされました。Arm64Xバイナリの作成が技術的に困難な場合、開発者はArm64Xの純粋なフォワーダーDLLを作成することができます。[52]
以下のアプローチは、同じ目的のマシン コードの複数のバージョンが同じファイルに提供されるという点で、ファット バイナリに似ています。
2007年以降、異種プラットフォーム向けの特殊なコンパイラの中には、複数の種類のプロセッサ上で並列実行するためのコードファイルを生成するものがあります。例えば、 Intel EXOCHI(Exoskeleton Sequencer)開発スイートのCHI(C for Heterogeneous Integration)コンパイラは、マルチスレッド用のOpenMPプラグマの概念を拡張し、異なる命令セットアーキテクチャ(ISA)のコードセクションを含むファットバイナリを生成します。これにより、ランタイムローダーは、異種システム環境内の複数の利用可能なCPUおよびGPUコア上で並列実行を動的に開始できます。 [53] [54]
2006年に導入されたNvidiaの並列コンピューティングプラットフォームCUDA(Compute Unified Device Architecture)は、GPU上で汎用コンピューティング(GPGPU)を可能にするソフトウェアです。LLVMベースのコンパイラNVCCは、 PTX仮想アセンブリ(テキスト形式)を含むELFベースのファットバイナリを作成できます。CUDAランタイムドライバは、これをジャストインタイムコンパイルして、実際に存在するターゲットGPU用のSASS(Streaming Assembler)バイナリ実行コードに変換します。実行ファイルには、CUDAランタイムがロード時に選択できる、1つまたは複数の特定のGPUアーキテクチャ専用の実行コードセクションを含むCUDAバイナリ(cubinファイル)も含めることができます。 [55] [56] [57] [58] [59 ] [60]ファットバイナリは、2007年に導入されたGPUシミュレータであるGPGPU-Sim でもサポートされています。[61] [62]
Multi2Sim(M2S)は、OpenCL異機種システムシミュレータフレームワークです(当初はMIPSまたはx86 CPUのみでしたが、後にAMD / ATI EvergreenやSouthern Islands、Nvidia FermiやKeplerファミリーなどのARM CPUとGPUもサポートするように拡張されました)[63] ELFベースのファットバイナリもサポートしています。[64] [63]
GNUコンパイラコレクション(GCC)とLLVMにはファットバイナリ形式はありませんが、リンク時最適化(LTO)用のファットオブジェクトファイルはあります。LTOはコンパイルをリンク時に遅延させるため、オブジェクトファイルには中間表現(IR)を格納する必要がありますが、一方で機械語も格納する必要がある場合があります(速度や互換性のため)。IRと機械語の両方を含むLTOオブジェクトはファットオブジェクトと呼ばれます。[65]
同じ命令セットアーキテクチャ向けのプログラムやライブラリであっても、プログラマは古いCPUとの互換性を保ちながら、新しい命令セット拡張を利用したい場合があります。これは関数マルチバージョン化(FMV)によって実現できます。同じ関数の複数のバージョンをプログラムに記述し、コードの一部がCPUの能力(CPUIDなど)を検出して、どのバージョンを使用するかを決定します。Intel C++コンパイラ、GCC、LLVMはすべて、マルチバージョン化された関数を自動的に生成する機能を備えています。[66]これは、意味的な影響を与えない動的ディスパッチの一種です。
多くの数学ライブラリは、CPUの能力に応じて自動的に選択される手書きのアセンブリルーチンを備えています。例としては、 glibc、Intel MKL、OpenBLASなどが挙げられます。さらに、glibcのライブラリローダーは、特定のCPU機能に応じた代替パスからのロードをサポートしています。[67]
マティアス・R・ポールとアクセル・C・フリンケによって考案された、バイトレベルの粒度で似たようなアプローチは、実行ファイルに埋め込まれた小さな自己破棄、緩和、再配置ローダーと任意の数の代替バイナリコードスニペットによって、動的デッドコード除去(DDCE)の形式を通じて、ロード時に特定のターゲット環境で特定の機能を実行する(または実行しない)ために必要なプログラムまたはドライバーのサイズまたは速度が最適化されたランタイムイメージを条件付きで構築するというものである。[68] [69] [70] [71]
COUNTRY.SYSCOUNTRY.SYS
[…] DOS保護機能 […] このアイデアは、Simeon Cran氏のMYZ80エミュレータのユーティリティに基づいています。これらのDOS保護ヘッダーは、
Z80
レジスタを一切変更しないという点でさらに優れています。マジックシーケンスはEB 52 EB: […] XCHG […] MOV D,D […] XCHG […] ですが、これはDOSコードがプログラムの開始位置からかなり離れた位置で実行されることを意味します。 […] 自己解凍型の
PMArc
アーカイブを使えば、さらに楽しむことができます。 1 つを […] defb 0EBh、018h、'-pms-' […] で開始すると、PMA ユーティリティによって有効なアーカイブとして扱われ、
8086
プロセッサが 011Ah に、Z80 プロセッサが 0130h に送信されます。 […]
[…] バイトシーケンス […] EB 03 C3 yy xx […]これらの5バイトを先頭として
.COMファイルを作成すると […] 'JMP SHORT 3' が表示され、その後に3バイトのゴミバイトが続きます。[…]
Z80の
逆アセンブリを見ると
[…] これは 'EX DE,HL; INC BC;' と解釈されます。 […] 3番目のバイトは「JUMP」で、その後にyy xxで指定された16ビットのアドレスが続きます […]
MS-DOS
および[…]
CP/M
で実行される.COMファイルが作成されます[…]
(注: 著者は Z80 について説明していますが、このシーケンスは8080および互換プロセッサでも動作します。)
[…] FATBIN 1.00 -
CP/M
.COMファイル
と
DOS
.COMファイルを結合し、両方のプラットフォームで動作するファイルを作成します。[…] 以下のファイルの作成に使用されました: […] MSODBALL 2.05 - フロッピーディスクを
Amstrad
706k形式とDOS 706k形式間で変換します。[…] どちらのプログラムもCP/M-80とDOSで動作します。[…]
CP/M
版のソースが含まれています。[…] DSKWRITE.ASMには
DOS
版のソースが含まれています
。[…] 単一の
.COMファイル
を取得するには、FBMAKEを使用する必要があります。[…]
[7] (注:FATBNSEA.COMパッケージのFBMAKEについて言及しています。)
[…]
自己解凍アーカイブ
は、多数の小さなファイルを含む
.COMファイル
です。アーカイブを実行すると、その中の小さなファイルが作成されます[…] 自己解凍アーカイブプログラムは、
DOS
(2以降)または
CP/Mで実行でき、結果は同じです。Unixで
解凍
するには
、ZXCCを使用できます[…] FATBNSEA.COM[…] FATBINは、CP/M-80の.COMファイルとDOSの.COMファイルを結合して、両方のシステムで動作するファイルを生成します。 […] M3C4SEA.COM […] M3CONV バージョン 4 -
.Z80 または .SNA 形式の
Spectrumスナップショットを
Multiface 3
形式に変換します(Multiface 3から
Z80
形式への変換は PC のみ)。 […] PMSFX21X.COM […]
PMSFX
は、これらの自動解凍アーカイブを生成するために使用されたプログラムです。このバージョン (2.11) では、CP/M または DOS で自動解凍されるアーカイブを生成できます。PMSFX を使用するには
PMARC が
必要です。新機能: DOS では、正確なファイルサイズをサポートします。 […] SP2BMSEA.COM […] Stop Press Canvas ファイルを
Windows の
.BMP に変換します […]
[8]
[…] 私は、
DOS
と
CP/M
で解凍できない
.COMファイル
(最初の3バイトは有効な
Z80
コード、有効な
8086
コード、有効な
PMAヘッダー)を生成する
PMSFX
のバージョンを作成しました。[…]
自己解凍型アーカイブ
として
。[…]
[…] このような違いが疑われる理由は、バージョン3.2xが
CP/M-86
もサポートしていたためです(
オーバーレイは
DOS
とCP/M-86で同一で
、メインの実行ファイルのみが異なります) […]
.OVR
ファイルはDOSとCP/M-86で100%同一で、実行時にフラグ(
WordStar 3.20の
マニュアルに明記されています)で切り替えます […] WordStarのOSインターフェースは非常に狭く、抽象化されています […] WordStar 3.2xのオーバーレイは、DOS版とCP/M-86版で100%同一です。 INT 21h (DOS) と INT E0h (CP/M-86) のどちらを呼び出すかを選択するランタイムスイッチがあります。WS.COM は DOS と CP/M-86 で同じではありませんが、おそらくそれほど大きな違いはありません。[…]
[…] FreeKEYBは[…] 真の.COMおよび.SYSドライバー(小型モデル)を1つにまとめたものです。最初のJMPを安全に上書きできます。これが私が「トリッキーなヘッダー」と言った理由の一部です。[…] FFFFh:FFFFhを3バイトジャンプと保留中のDB FFhに置き換えることができます。MS-DOS、PC DOS、DR-DOS、そしておそらく他のDOSの問題にも動作します。[…]
TSR
とデバイスドライバーの両方を1つにまとめることができるように、ドライバーにSYSデバイスドライバーヘッダーを追加します。
これは、FreeKEYBアドバンスドキーボードドライバーに似ています。[…]
INSTALL =はDR DOS 3.41以降でサポートされており、DR DOSは
[D]CONFIG.SYS
ディレクティブの順序を保持する
ため、 DR
DOS
では実際には必要ありません。 […] しかし、[…]
MS-DOS
/
PC DOS
システムでの柔軟性が向上します。[…] ファイル内の順序に関係なく、常にINSTALL =ステートメントよりも前に
DEVICE
=ディレクティブが実行されます。 […] ソフトウェアは、マウスドライバをデバイスドライバとして提供することを要求する場合があります。これは、昔からマウスドライバは常にデバイスドライバであったためです。これらのマウスドライバは、使用するプロトコルに応じて固有のデバイスドライバ名(例えば、
マウスシステムモードの場合は「
PC$MOUSE
」
)を持っており、一部のソフトウェアは、使用するマウスの種類を特定するためにこれらのドライバを検索する場合があります。[…] もう1つの利点は、デバイスドライバは通常、メモリ消費量が少ないことです(
環境変数や
PSPは
不要
)。[…] これは基本的に、扱いにくいファイルヘッダー、コマンドラインを解析するための別のコード、異なるエントリポイントと終了行、そしてORG 0 / ORG 100hの違いを克服するためのいくつかのセグメントマジックです。デバイスドライバの
自己ロードハイディング
は、ドライバヘッダーをそのままにして、ドライバの残りの部分のみを再配置する必要があるため、少し扱いにくくなります。[…]
カルデラの OpenDOS 7.01 をアップデートして、
IBMBIO.COM
のスタートコードを修正してください - 正常なプログラムを開始してください - 完全なコマンドを実行してください。バージョン Einzug halten wird の機能をすべて使用すると、次の操作が可能になります。
(注:NWDOSTIP.TXTはNovell DOS 7とOpenDOS 7.01に関する包括的な資料であり、多くの未文書化の機能や内部構造の説明も含まれています。これは著者が
MPDOSTIP.ZIP2001年まで維持し、当時多くのサイトで配布していた大規模なコレクションの一部です。提供されているリンクは、HTMLに変換された古いバージョンのファイルを指していますNWDOSTIP.TXT。)[9]
[…] 「RST 0」というオペコードがあり、これを実行すると
ウォームブート
が発生します。Z3TXTモジュールを含むファイルは実行されるべきではありませんが、1バイトを犠牲にすることで、そのような可能性から身を守ることができます。ヘッダーには、「
Z3TXT
」という文字列とそれに続くヌルバイト(0)も含まれていました。多くの
Z-System
モジュールにはこのような識別子が含まれています。このカテゴリには、常駐コマンドパッケージ(RCP)、フローコマンドパッケージ(FCP)、環境記述子モジュール(
Z3ENV
)が含まれます。Bridger Mitchellの[…] JETLDR.COMなどのプログラムは、これらのモジュールをファイルからメモリにロードし、ID文字列を使用してファイルを検証できます。つまり、ユーザーが指定した種類のモジュールであることを確認します。これにより、ユーザーのミスや破損したファイルを検出できます。[…] したがって、ヘッダーは次のようになります。[…] rst […] db 'Z3TXT',0 ; ヌル終端ID […] ; 12345678 ; 8文字である必要があります[…] db 'PROGNAME' ; スペースで埋める[…] ; 123 ; 3文字である必要があります[…] db 'ENG' ; 言語名[…] dw LENGTH ; モジュールの長さ[…]
[15][16]
ASCII
ファイルの終了は、
CP/Mの読み取り操作によって返される
制御Z
文字(1AH)または実際のファイル終了
によって示されます。ただし、マシンコードファイル(例:
COMファイル
)に埋め込まれた制御Z文字は
無視され、CP/Mによって返されるファイル終了条件は読み取り操作の終了に使用されます。[…]
(56ページ)
[…] CP/Mは、ファイル内の最後のデータ文字の後にCONTROL-Z文字を配置することで、 ASCIIファイルの終わりをマークします。ファイルに128の倍数の文字が含まれている場合、CONTROL-Zを追加すると127文字が無駄になるため、CP/Mはそうしません。CONTROL-Z文字をファイル終了マーカーとして使用することは可能です。これは、ASCIIファイルではCONTROL-Zがデータとして使用されることはほとんどないためです。ただし、非ASCIIファイルでは、CONTROL-Zは他の文字と同じくらい発生する可能性があります。したがって、ファイル終了マーカーとして使用することはできません。CP/Mは、非ASCIIファイルの終わりをマークするために別の方法を使用します。CP/Mは、ファイルに割り当てられた最後のレコード(ディスクスペースの基本単位)を読み取ると、ファイルの終わりに到達したと見なします。各ファイルのディスクディレクトリエントリには、そのファイルに割り当てられたディスクレコードのリストが含まれています。この方法では、ファイルの内容ではなくサイズに基づいてファイルの末尾を特定します。[…][17][18]
[…] FreeKEYBは、ロード先のマシンの種類、キーボードの種類、レイアウト、国、コードページ、インストールされているマウスとビデオアダプタの種類、そのシステムにロードされている他のドライバ、オペレーティングシステムとロードおよび再配置方法、含まれる個々の機能、コマンドラインで指定された設定オプションに応じて、初期化時にドライバのランタイムイメージを構築します。サポートされているコマンドラインスイッチとオプションの数が非常に多いため[…](約50個のスイッチ[…]、複数の設定が可能)無数の依存関係を持つ機能の組み合わせが多数存在し、[…]、結果として[…]、無数の[…]異なるターゲットイメージが生成されます。 FreeKEYB の動的デッドコード除去技術は、[…] これらの […] 依存関係を解決し、[…] デッドコードとデータを削除します […] は、[…] 従来の TSR プログラミングのように、ある程度限られた数のモジュールまたはサブルーチン全体を含めたり除外したり、一部のディスパッチ テーブルを修正したりするだけではありません。[…] バイト レベルで動作し、[…] 大きなルーチンの途中にある個々の命令を削除できます […] 特定のケースを処理したり、特定の機能をサポートしたりするためにコード全体に分散されています […] 特別なツールを使用してコードを分析します […] および […] フィックスアップ テーブルを自動的に作成します […] 条件定義を使用してさまざまなケースを宣言します […] アセンブリ時だけでなく初期化時にもオプションです […] ランタイム イメージに少なくともある程度のデッドコードが残るオーバーヘッドなしで […] これらの条件間のすべての依存関係を追跡し、ランタイム イメージを動的に構築および再配置し、これらの小さな変更および移動するバイナリ部分間のすべての参照を修正します […] 小さな .COM/.SYS スタイルのモデルを使用できます […] は初期化時に実行されます […]
[…] 独自の[…]機能である
「動的デッドコード除去」
により、インストール時に[…] ドライバのどのコンポーネントが必要で、どのコンポーネントが不要かを指定できます。これは、これまでDOSでは見たことのない、動的ロード可能なモジュール化と遅延リンクのレベルに達しています。スクリーンセーバー、マクロ、電卓、マウスサポート、その他<ほぼすべて>が不要な場合は、コマンドラインで指定できます。FreeKEYBは、ルーチン間の依存関係をすべて考慮しながら、ドライバがイメージをターゲット位置に再配置して常駐する前に、その機能を扱うコードフラグメントを完全に削除します。[…]
[…] brandneue[s] 機能、
デッド コード排除の機能
、宝石ではなく、最高のインストールと再構築を行うため、コードの日付を変更する必要があります (zB wenn jemand ein) Bestimmtes FreeKEYB-Feature nicht benötigt)。 […]