web-dev-qa-db-ja.com

64ビットバージョンから32ビットプログラムを作成するにはどうすればよいですか?

現在32ビットの市場は小さいため、多くのソフトウェアは64ビットマシンのみをサポートしています。ただし、32ビットマシンで立ち往生している人にとっては、これは新しいバージョンをインストールできないことを意味し、セキュリティの問題につながる可能性があります。一例は Firefox/Waterfox です。

一般に、64ビットインストール(.exe、.msi)から32ビットプログラムを作成する方法はありますか?


詳細: ブラウザのセキュリティを優先する必要があるのはなぜですか?

5
Ooker

いいえ、これは不可能です。 x86とx64がどのように作成されたか、そしてこれが一般的なプログラミングにどのように影響するかについての基本を説明する必要があることを考えると、理由がかなり広い、あるいはSuperUserには広すぎるかもしれません。

しかし、簡単に説明すると、それはこれに帰着します:

以前は、16ビットプロセッサがありました。その後、Intelはx86としても知られる最初の32ビットプロセッサを製造しました。これは8086、80286(略して286)などです...これは基本的に16ビットプロセッサの修正で、追加の命令セットが追加されています。インテルはプロセッサーシリーズの新しいリリースごとに、より多くの命令セットをプロセッサーファミリーに追加し、結局、命令セットに多くの命令を含めました。 Intelは古い命令セットを単に削除することはできませんでした。これは、下位互換性がないことを意味し、Intelは古いプロセッサのサポートを継続したいと考えていました。

プロセッサは32ビットであるため、上限、つまり最大の32ビット数があります。これは、メモリ割り当てが最大で約3.5GBになることを意味します。

当時、コンピューターはそれほど強力ではなかったので、Intelが最初から64ビットを目指すとしたら、同じ数値の計算に多くの時間が費やされ、計算する数値が大きいという理由だけでパフォーマンスが低下することを意味します。

32ビットプロセッサに加えて、長い間非常にうまく機能していました。

ある時点で、AMDは市場に参入し、64ビットプロセッサを導入しました。 AMDは、32ビットとの下位互換性を可能にするために32ビットのIntel命令セットをそのまま維持しながら、64ビットでの作業を可能にする独自の命令セットを作成しました。

それらが実際には異なる命令セットであることを考えると、32ビットプログラムを作成するプログラマーは、64ビットプログラムを作成するときとは異なるルーチンを呼び出します。

これがなぜ難しいのかを説明したところで、プログラミングの観点から問題を説明し続けましょう。

プログラムをコーディングするときは、最初にコードを記述します。コードが32ビットプログラムと下位互換性がある場合、64ビットの数値を使用することも、3,5ギガを超えるメモリを同時にアドレス指定することもできません。基本的に、32ビットプログラムが直面する制限を超えることはできません。超えた場合、プログラムがクラッシュします。

これでコードが作成されたので、実際にプログラムを実行できるのはあなただけです。他の人がプログラムを実行できるようにするには、コードを実行可能ファイルにコンパイルする必要があります。これは、読みやすいコードがプロセッサが理解できる命令に変換されることを意味します。コンパイル時に、プログラムをx86またはx64で実行するかどうかを指定すると、コンパイラーはそのプロセッサーアーキテクチャーに基づく命令セットを使用してコードを生成します。

ご覧のとおり、実行可能ファイルを変更して別の実行可能ファイルで機能させることはできません。最初にプログラムをコードに逆コンパイルしてから、別の命令を使用して再コンパイルする必要があります。

とは言っても、x86用にコンパイルされたプログラムはx64でネイティブに動作するので、プログラマーがx64アーキテクチャーの制限を超えるため、x64プログラムを作成すると想定しても安全です。したがって、x64バージョンをx86バージョンに変更したとしても、32ビットプログラムで実行できる制限を超えるため、プログラムが不安定になる可能性があります。

12
LPChip

理論的にはそれが可能です!

ニュートラルな bytecode / internal Representation から、最新のコンパイラ/ JITterの動作のように、特定のアーキテクチャのバイナリに変換する方法があります。現在のアーキテクチャで別のアーキテクチャのプログラムを実行する emulators もあります。 Bochs および qemu は、最も有名なものの2つです。見る:

それにもかかわらず、基本的にすべてのシステムとライブラリの呼び出しをエミュレートする必要があるため、単一のバイナリに対してそのようなコンバーターを作成している人はまだいません。その場合は、とにかくエミュレーター全体を実行する方がよいでしょう。 Qemuにはユーザースペースのみをエミュレートする機能もあるため、本格的なOSがなくても、必要なライブラリとともにプログラムを実行することが実際に可能です。しかし、いつものように、エミュレーションは、Webブラウジングやメディア再生など、パフォーマンスを重視するものには適していません

ただし、x86 PCが2ビットのみの場合は、すでに10年以上経過していることを意味します。ほとんどすべてのIntel CPU Pentium 4 Prescottから2004以降 (一部のAtom CPUを除く)およびすべてのAMD CPU 20以降のAthlon64以降 は64ビット対応です。更新する時が来ました。

PCがx86_64およびVT-xをサポートするのに十分新しい場合は、32ビットホスト内で64ビット仮想マシンを 実行できます ただし、お勧めできません。パフォーマンスはさらに低下します。内部に32ビットのVMを含む64ビットのホストを実行するよりも。 64ビットOSは、多くの人が考えているように32ビットOSと比較して2倍のメモリを必要としないため、 2GBのRAM しかない場合でも、64ビットOSは一般的に高速です。レジスタの数が2倍になるなどの理由で。 1〜2 GBのRAMは議論の余地がありますが、64ビットを使用します


とは言うものの、セキュリティ対策に関しては、開発者全員が64ビットシステムを実行しているため、最近の32ビットOSはしばしばセキュリティパッチの最新版です。たとえば、MeltdownパッチとSpectreパッチは、64ビットLinuxにパッチが適用されてから半年以上後に32ビットLinux にプッシュされます 。 Meltdownパッチは64ビットWindows 10 build 1507 以降に提供されていますが、32ビットユーザーは build 1511 以降のみ保護されています。また、パッチが適用されている場合でも、このような古いマシンは通常 パフォーマンスへの影響がはるかに大きくなります速度低下を相殺するための新しい手順や機能がないため、 。その理由により、MS は、ユーザーから明示的に指示されない限り、一部の古いPC でパッチを有効にしません。テスターの数が大幅に少ないため、パフォーマンスの低下に加えて、32ビットパッチはバグが発生する可能性が高くなりますになります。 Linuxの32ビットカーネルがメルトダウンのために緩和されて以来バギーになっているのを参照してください

IntelのMeltdownの脆弱性が公開されてから(そしてx86_64が軽減されてから)、 LinuxKPTIがx8632ビット をサポートしてMeltdownを軽減するのを確認するのに数か月かかっただけではありません(1月の開示から7月のメインラインの準備まで) 、しかし、2018年の夏から現在[2019年7月28日]までカーネルに存在していた32ビットのみのバグがLinux5.3で公開されることになりました。

場合によってはまったくパッチが適用されないユーザーベースが不足しているため、多大な労力を費やすインセンティブがほとんどありません。この問題は、ハードウェアのバグである場合、ハードウェアのサポートなしで修正不可能です。たとえば、SpectreやL1TFのような最近のサイドチャネル攻撃も更新されたマイクロコードを必要とするため、CPUやメインボードの製造元がファームウェアの更新をリリースしない場合、あなたは運が悪いです!これらのバグは過去20年間にCPUに影響しますが、非常に古いシステムにパッチを提供することはできません。 Windows 7も Pentium 3のサポートを落としました SSE2をサポートしないとパッチを適用するのが難しいため、またはそれらのCPUで実行する人が少なすぎるため.

32ビットWindowsも、次の理由でより脆弱です。

エミュレーターで64ビットOSを実行すると、さらに遅くなります。また、クロール速度を受け入れてエミュレーターを使用した場合でも、ホスト上のマルウェアは、このような脆弱なシステムの仮想マシンを攻撃する可能性があります。繰り返しになりますが、本当にセキュリティに関心がある場合は更新する必要があります。そうしないと、安全性の低いシステムを無期限に使用する必要があります。

参考文献:

9
phuclv

これは技術的に可能です。このプロセスは バイナリ変換 と呼ばれます。

ほとんどの場合、これは、異なるプラットフォーム用のエミュレーター(たとえば、x86ではARM、ARMではx86))、またはハードウェアアクセラレーションが利用できない仮想化で実行されます。

直面する最大の問題は、ほとんどのプログラムを単純に単独で実行できないことです。それらは、オペレーティングシステムの [〜#〜] abi [〜#〜] に依存します。これは通常、アーキテクチャによって異なります。つまり、OSとのすべてのやり取り(API呼び出しなど)のために変換層を追加する必要があり、その時点でphuclvの回答に記載されているOS全体をエミュレートする必要があります...

5
Bob

プログラムを32ビットターゲットに再コンパイルします

あなたの質問は64ビットのバイナリを持っていて32ビットのバイナリとして実行したいと思っていましたが、これは非常に難しく、最終的には エミュレータを使用 またはその他の複雑な問題が発生します。

ただし、(Firefoxの場合のように)高水準言語の元のコードがある場合は、おそらくそれを32ビットコードにコンパイルできます。

ここで、私は LPChip回答 の最後の段落に敬意を表して同意しませんプログラマーはx86アーキテクチャの限界を破ろうとしているのでx64プログラムを作成します。これは、デフォルトのターゲットであるため、ネイティブアーキテクチャと一致するため、またはユーザーが十分なRAMを持っている場合に、より多くのメモリを使用できるというメリットを享受するために行うことができます。

32ビットのものから作られた64ビットカウンターのようないくつかの機能は、ネイティブレジスタを使用するよりもわずかに遅くなります。プログラムが64ビットに固有の機能(インライン64ビットアセンブリなど)を使用している場合、それは機能しません。責任は主に、使用されている高級言語でのコンパイラーのサポートにあります(そして、コードは適切に記述されているため、最初から非常に移植性があります)。

Firefox/Waterfoxの構築に焦点を当てると、初心者のための単純な努力ではありません(現在のブラウザは独自のOSのようなものです)。FirefoxQuantumでは、さらにRustコンパイラが必要です。それでも、Linuxディストリビューションは依然としてFirefoxの32ビットバージョンをコンパイルしており、32ビットで実行できることを示しています。

1
Ángel