すべてのコンピューターに対応したユニバーサルアセンブリ言語は可能ですか?


23

アセンブリ言語についていくつか質問をしたいと思います。私の理解では、機械語に非常に近いため、より高速で効率的になります。

さまざまなコンピューターアーキテクチャが存在するため、異なるアーキテクチャ向けにアセンブリで異なるコードを記述する必要がありますか?もしそうなら、なぜAssemblyではない、一度書く-どこでも言語の種類を実行する?単純に汎用化するのは簡単ではないので、一度書くだけで、さまざまな構成のほぼすべてのマシンで実行できますか?(それは不可能だと思いますが、具体的で詳細な答えが欲しいです)

Cが私が探している言語だと言う人もいるかもしれません。私は以前にCを使用したことはありませんが、おそらくJavaよりも高速かもしれませんが、Cはまだ高レベル言語だと思います。私はここで間違っているかもしれません。


10
どんな研究をしましたか?より良い質問をするために、質問する前に調査を行うことを期待します。アセンブリ言語で書かれたものがたくさんあります。
DW

4
質問する前に、かなりの量の研究/自習を行い、どのような研究を行ったのか質問してください。この場合、研究には、関連するウィキペディアの記事(アセンブリ言語やコンピューターアーキテクチャなど)の読み取りやコンピューターアーキテクチャの教科書の読み取りが含まれます。これをより良い質問にするには、まだ調査していない場合は調査を行い、質問を編集して、行った調査を説明します。多くの場合、この種の研究は、より良い質問を作成するのに役立ちます。いずれにせよ、回答者が既に知っていることを繰り返すことを避けるのに役立ちます。
DW

15
アセンブリと呼ばれる言語がない理由を理解することから始めます。
ラファエル

2
Cの移植性に関する「古典的な」問題の1つは、異なるハードウェア上の異なるプリミティブ(整数など)のサイズであり、他にも引用されているものがあります。
-vzn

3
これは技術的な問題というよりも社会的な問題です。すべてのCPUメーカーに、同じマシン言語をCPUに受け入れさせるよう説得する必要があります。(実際には、偶然にもx86はほとんどこれになりそうでした-スマートフォンが離陸しました)
-user253751

回答:


45

アセンブリ言語は、コンピューターの命令セット用の命令を記述する方法で、人間のプログラマーが少し理解しやすい方法です。

アーキテクチャごとに異なる命令セットがあります。許可される命令のセットは、アーキテクチャごとに異なります。したがって、一度だけ実行するあらゆる場所にアセンブリプログラムを作成することは望みません。たとえば、x86プロセッサでサポートされる命令セットは、ARMプロセッサでサポートされる命令セットとは大きく異なります。x86プロセッサ用のアセンブリプログラムを作成した場合、ARMプロセッサではサポートされていない命令が多数あり、その逆も同様です。

アセンブリ言語を使用する主な理由は、プログラムを非常に低レベルで制御でき、プロセッサのすべての命令を利用できることです。特定のプロセッサに固有の機能を利用するようにプログラムをカスタマイズすることによりで実行され、時にはプログラムを高速化できます。一度だけ実行するあらゆる場所での哲学は、基本的にそれと対立しています。


1
その質問は、私の回答の3番目の段落で既に回答されていると思います。あなたが言ったように、そのようなスキームは効率的ではないので、アセンブリ言語を使用する主要な理由と根本的に対立します。
DW

26
@nTuplyさまざまなマシンに対応するためにアセンブリ言語を変更するとすぐに、それは恐ろしくアセンブリスタイルの構文を備えた高レベル言語になります。高水準言語を使用することに決めたら、より使いやすい構文の言語を使用して、コンパイラーに苦労させることもできます。
デビッドリチャービー

15
異なるマシン用に翻訳される「アセンブリ言語」を持つのは完全に愚かな考えではありません。それは基本的にLLVMの「IR」だからです。ただし、Davidが提供する理由により、通常 LLVMアセンブリを作成しません。また、100回のうち99回は、ClangがCをLLVMに翻訳するよりも、書くのがひどい仕事になるでしょう。アセンブリ言語は、高レベル言語よりも潜在的に効率的ですが、最適化に利用できる典型的な時間があるほとんどの実際のプログラマーの手では、とにかく潜在能力に達しません。
スティーブジェソップ

9
@nTuply、それは存在します。アセンブリ外言語から機械語命令に移行するプロセスは、コンパイルと呼ばれます。
ポールドレーパー

3
@PJTraill最新のシステムのアセンブラーでコンパイラーを作成する理由は何もありません。ただし、最初のブートストラップ手順を除きます(ほとんどの場合、その時でもありません)。高水準言語で書かれたコンパイラーは、実際に保守可能である可能性が非常に高いです。また、コンパイラがCで記述されている言語は、Cよりも高速になります。。コンパイラの目的は、ある言語(ソース言語)から別の言語(通常、特定のアーキテクチャとOSのマシン言語)に翻訳することです。これは任意の言語で記述できます。
CVn

13

アセンブリ言語の定義は、アセンブリコードをマシンコードに直接翻訳できる言語であるということです。アセンブリ言語の各操作コードは、ターゲットコンピューターで1つの操作に変換されます。(まあ、それよりも少し複雑です。一部のアセンブラは、オペコードへの引数に基づいて「アドレス指定モード」を自動的に決定します。しかし、原則として、アセンブリの1行が1つの機械語命令に変換されます。)

アセンブリ言語のように見えるが、異なるコンピューター上の異なるマシンコードに翻訳される言語を発明することができます。しかし、定義により、それはアセンブリ言語ではありません。これは、アセンブリ言語に似た高レベル言語になります。

あなたの質問は、「フロートせず、水上を移動する他の方法があるが、ホイールとモーターがあり、陸上で移動できるボートを作ることは可能ですか?」という質問に少し似ています。答えは、定義上、そのような乗り物はボートではないということです。車のように聞こえます。


1
Cはしばしば「ポータブルアセンブリ言語」と呼ばれています。
ラリーグリッツ

2
@LarryGritz確かに。そして、Cが発明されたとき、それは画期的でした:それは、コンパイルされた使いやすさでアセンブリ言語の力の多くを提供しました。しかし、定義によって、それはまだコンパイル言語だ
ジェイ

8

世界中のすべてのコンピューターに1つのアセンブリ言語を使用することに対して、概念的な(あえてコンピューターサイエンスがない)理由はありません。実際、これにより多くのことがはるかに簡単になります。理論に関する限り、ファンキーな全単射まではとにかくすべて同じです。

ただし、実際には、目的ごとに異なるチップがあり、異なる目標に対応するさまざまな操作と設計原則(RISCとCISCなど)があり、それらを操作する命令セットとアセンブリ言語は異なります。最終的に、答えは、なぜ多くの異なるプログラミング言語があるのかを尋ねるときと同じです:異なる目標、異なる設計決定。

そうは言っても、当然のことながら、いくつかの共有インターフェースに到達するために抽象化のレベルを導入できます。たとえば、x86はかなり長い間、チップレベルで廃止されました。x86命令をプロセッサが実際に動作するものに変換する小さなハードウェアがあります。Cのような言語は、ハードウェア(おそらく非常に小さい言語)からさらに一歩進んで、Haskell、Java、Rubyなどの言語に至るまでです。はい、コンパイラーはコンピューターサイエンスの主な成果の1つです。コンパイラーは、この方法で懸念を分離できるようにするためです。


6
「もし間違いなく小さなものなら」-あなたの2種類のプログラマーがそこにいます。Cの基本操作はCPU命令セットに現れる種類のように見えるためCを低レベル言語と見なす人、およびC はマシンと同じ命令セットではないためCを高レベル言語と見なす人。
スティーブジェソップ

場合はアセンブリ言語使用すると、1つは、ハードウェアの特定のタイプ(または家族)のために生成されたマシンコードを完全に制御を与えることを意味し、与えられた瞬間に、私たちの世界では、「すべてのコンピュータの」一つの言語を定義することが可能であろうが、それは希望変化し続ける必要があります。確かに(適切に設計されていれば)新しいアーキテクチャのコーディングの学習曲線を短縮しますが、コンパイラがごく一部のアーキテクチャにのみ適用されるのではなく、それを使ってやりたい仕事を期待しています。コンピューターが抽象的なレベルで同じであるということは、ニシンであり、マシンコードに関するものです。
PJTraill

7

「一度だけ実行すれば書き込み」というフレーズは、その重要性に気付かずに言及します。それはのためのマーケティングのスローガンであるSun Microsystemsの商業の概念を発明した「仮想マシン」「バイトコード」おそらくアイデアは学界1に由来しているかもしれないが、Java用のST。このアイデアは、Javaライセンスの侵害によりSunによって首尾よく訴えられた後、Microsoftによって.Netのためにコピーされました。Javaバイトコードは、クロスマシンアセンブリまたはマシン言語のアイデアの実装です。Java以外のいくつかの言語で使用され、理論的には任意の言語をコンパイルするために使用できます。長年にわたる非常に高度な最適化の後、Javaはコンパイルされた言語のパフォーマンスに近づき、プラットフォームに依存しない高性能な仮想マシンテクノロジーの目標が一般的に達成可能であることを示しています。

あなたの要件に関連する初期段階/循環の別の新しいアイデアは、再計算プロジェクトと呼ばれ、他の目的に使用することができますが、科学研究のためのものです。アイデアは、仮想マシン技術を介して計算実験を複製可能にすることです。これは主に、任意のハードウェアで異なるマシンアーキテクチャをシミュレートするという考えです。


8
Sunは仮想マシンもバイトコードも発明しなかった。彼らは彼らからお金を稼ぐ最初のグループでさえなかった。Pコードを検索します。
jmoreno

@jmoreno:彼はSmalltalkを調べたいかもしれません。
ボブジャービス-モニカの復活

この記事は、太陽が発明した仮想マシン/バイトコードを主張していません。引用されていないが暗示されている他の歴史があります。ここで非常に関連性の高い別の重要なテクノロジー:Googleネイティブクライアント(クローム機能)
-vzn

5

高レベルの理由

あなたがそれについて考えるとき、マイクロプロセッサは驚くべきことをします:それはあなたが機械(洗濯機やエレベーターなど)を取り、安価で大量生産されたシリコンでカスタム設計されたメカニズムまたは回路のチャンク全体を置き換えることを可能にしますチップ。部品に多くのお金を節約し、設計に多くの時間を節約できます。

しかし、数え切れないほどのカスタムデザインに取って代わる標準チップです。すべてのアプリケーションに最適な単一の完璧なマイクロプロセッサは存在できません。一部のアプリケーションでは、電力使用量を最小限に抑える必要がありますが、高速である必要はありません。他のものは高速である必要がありますが、プログラムが簡単である必要はなく、他のものは低コストである必要があります。

したがって、マイクロプロセッサにはさまざまな「フレーバー」があり、それぞれに長所と短所があります。全員が互換性のある命令セットを使用することが望ましいです。これにより、コードの再利用が可能になり、適切なスキルを持つ人材を見つけやすくなります。ただし、命令セット、プロセッサのコスト、複雑さ、速度、使いやすさ、および物理的制約に影響するため、妥協点があります。「主流」の命令セット(およびマイナーな命令セット)がいくつかあり、各命令セット内には、異なる特性を持つ多くのプロセッサがあります。

ああ、技術が変化すると、これらのトレードオフがすべて変化するため、命令セットが進化し、新しいセットが出現し、古いセットが消滅します。たとえ今日の「最高の」命令セットがあったとしても、それは20年ではないかもしれません。

ハードウェアの詳細

おそらく、命令セットでの最大の設計決定はワードサイズ、つまりプロセッサが「自然に」操作できる数値の大きさです。8ビットプロセッサは0〜255の数値を処理し、32ビットプロセッサは0〜4,294,967,295の数値を処理します。ある人のために設計されたコードは、別の人のために完全に再考される必要があります。

ある命令セットから別の命令セットに命令を変換するだけの問題ではありません。異なる命令セットでは、完全に異なるアプローチが望ましい場合があります。たとえば、8ビットプロセッサではルックアップテーブルが理想的ですが、32ビットプロセッサでは算術演算が同じ目的に適しています。

命令セットには他にも大きな違いがあります。ほとんどの指示は4つのカテゴリに分類されます。

  • 計算(算術と論理)
  • 制御フロー
  • データ転送
  • プロセッサ構成

プロセッサは、実行できる計算の種類と、制御フロー、データ転送、およびプロセッサ構成へのアプローチ方法が異なります。

たとえば、一部のAVRプロセッサは乗算も除算もできません。一方、すべてのx86プロセッサーは可能です。ご想像のとおり、乗算や除算などのタスクに必要な回路を削除すると、プロセッサがよりシンプルで安価になります。これらの操作は、必要に応じてソフトウェアルーチンを使用して実行できます。

x86では、算術命令がオペランドをメモリからロードしたり、結果をメモリに保存したりできます。ARMはロードストアアーキテクチャであるため、メモリにアクセスするための専用の命令がいくつかあります。一方、x86には専用の条件分岐命令がありますが、ARMでは事実上すべての命令を条件付きで実行できます。また、ARMではほとんどの算術命令の一部としてビットシフトを実行できます。これらの違いは、パフォーマンス特性の違い、チップの内部設計とコストの違い、アセンブリ言語レベルでのプログラミング手法の違いにつながります。

結論

ユニバーサルアセンブリ言語を使用できないのは、アセンブリコードをある命令セットから別の命令セットに適切に変換するには、コードを最初から設計し直す必要があるためです。コンピューターではまだできません。


素晴らしい答えです!プログラミングが必要なコンピューティングアイテムが私たちのいたるところにあることを、人々は十分に理解していません。画面上で実行中のアプリケーションだけではありません。毎年何十億個のチップが製造されていますか?
phs

4

DWによる素晴らしい回答に追加します。1つのアセンブラーが必要な場合は、すべてのアーキテクチャを維持し、それらの間で完璧なトランスレーターを作成し、何をしているかを完全に理解する必要があります。
アーキテクチャごとに高度に最適化されたコードの中には、最適化を解除し、より抽象的なレベルで理解し、互いに最適化する必要があるものがあります。
しかし、これが可能であれば、完璧なCコンパイラが得られ、純粋なアセンブリで記述することはまったく有益ではありません。
アセンブラーを使用する主なポイントはパフォーマンスです。これは、最近のコンパイラーでは絞り込めません。
そのようなプログラムを書くことは、既存のコンパイラよりもさらに難しく、作成されているすべての新しいアーキテクチャを維持することはさらに難しくなります。
「1つだけ」のプログラムの場合、完全な後方互換性も意味します。


ほとんどの場合、gccはプログラマーができるよりも優れた最適化を実行します。アセンブラーを使用する主な目的は、レジスターへのアクセスなど、Cではできないことを行うことです。Linuxソースツリーを見ると、アセンブリを使用しているのとほぼ同じです。
スリーブマン

@slebetman-gccを使用すると、アセンブリに頼らずに変数をレジスタに入れることができます。
ジルカハニカ

@JirkaHanika:特別な命令でアドレス指定されたCPUレジスタまたは特別な目的のハードウェアレジスタについて話していますか?slebetmanは後者を意味すると思います。
PJTraill

「すべてのコード」-「GCCの方が良い」=「アセンブラーを使用する」。はい、アセンブラを挿入しなくてもレジスタにアクセスできます。

@PJTraill-Slebetmanのコメントは一般的に優れており、おそらく回答に組み込む必要があります。しかし、彼の例(レジスタアクセスとLinuxソースツリー)はどちらも、gcc拡張を使用してCで実行できない優れた例ではなく、一般的な誤解を招く可能性があります。それらを置き換えるか省略する必要があります。(今日何かをするHW命令がある場合、対応するgcc拡張が今から1年あります。常にではありませんが、非常に頻繁です。例:年齢。)
Jirka Hanika

3

マイクロソフトは、MSILを中間アセンブリ言語として発明しました。プログラムはC#またはVB.NetからMSILにコンパイルされます。実行時に、MSITは、JITコンパイラーを使用して、MSILを実行していたマシンのマシンコードにコンパイルされました。MSILを含むファイルは、プログラムを開始するためのX86の先頭にいくつかの指示がある.EXEファイルでした。ARMプロセッサでは、プログラム名の前に「mono」という単語を入力して実行します。


「中間アセンブリ言語」と「仮想マシン」の違いは何ですか?
ボブジャービス-モニカの復活

@BobJarvis:1つはコードで、もう1つはインタープリターです。中間アセンブリとバイトコードの違いは何
ですか?slebetman

これは質問に答えていないようです。各マシンが異なる方法でMSILをコンパイル/アセンブルする限り、それについて普遍的なものはなく、そのようなコンパイルの目的は汎用機能の移植であり、DWが指摘する特定の命令セットの活用ではありません(またはa)アセンブラーを使用する理由。
PJTraill

3

前述のように、LLVMはこれまでのところこれに最も近いものです。本当に普遍的な言語に対する大きな障壁は、暗黙のトレードオフに関連する基本的な違いです:並行性、メモリ使用、スループット、レイテンシ、および電力消費。明示的にSIMDスタイルで記述した場合、使用するメモリが多すぎる可能性があります。明示的にSISDスタイルで記述すると、次善の並列化が行われます。スループットを最適化すると、遅延が発生します。シングルスレッドのスループット(クロック速度など)を最大化すると、バッテリーの寿命が短くなります。

少なくとも、コードにはトレードオフの注釈を付ける必要があります。最も重要なことは、言語がコンパイラに論理的な矛盾を最適化および検出するための多くの余地を与える優れた代数/型プロパティを持つことです。

次に、未定義の動作の問題があります。C言語とアセンブリ言語の速度の多くは、未定義の動作によるものです。実際に発生する未定義の動作を認める場合、それらを特別なケースとして処理することになります(つまり、アーキテクチャおよびコンテキスト固有のハック)。


0

おそらくあなたが探しているのは、誰もがコマンドの記号に同意するユニバーサルターニングマシン表記です。(https://en.wikipedia.org/wiki/Universal_Turing_machine

Turning Acceptable言語を基になるベンダー固有のマシンコードに翻訳し、コンピューターと呼ばれるもののためにビルドされる「アセンブラー」。

The Art of Computer Programmingには、これがどのように見えるかの例があります。

しかし、「すべてのコンピューターで使用できる市販の汎用言語ではない理由」という質問を考えてみてください。最も支配的な影響は次のとおりです。(2)異なるブランドのマシンとベンダーとの間の経済性、提供、非互換性は、ビジネス戦略であり、マシンを設計するための限られたリソース(時間/お金)の結果です。


問題は、「ユニバーサルチューリングマシン」の意味で普遍的なアセンブリ言語ではなく、任意のコンピューターをプログラムするために使用できるアセンブリ言語について尋ねていることです。
デビッドリチャービー

1
Church-Turingは、UTCはプログラム可能なコンピューターなら何でもできることを示しています。有限の物理ストレージの問題は別として。UTCのアセンブリ言語は非常に実現可能です。しかし、私が言ったように、文化的および経済的な実用性は、市場での実際の実装と採用を制限するかもしれません。
クリス

最大の問題、つまりパフォーマンスが欠落しています!ハードウェアに依存しないという高い目標のためだけに、何千倍も遅い言語を使用するのはなぜですか?チューリングマシンは、実用的なコンピューティングのためのひどいモデルです。
アルテリウス

1
コメント作成者は、主張を裏付けるためにコンピューターサイエンスを提供したいと思いますか これは、すべてのコンピューターサイエンスフォーラムの後です。
クリス

1
私はCSの専門家ではありません。しかし、私が信じているのは、フォンノイマンアーキテクチャは、プログラミングとパフォーマンスのバランスをとる素晴らしい技術であり、チューリングマシンの目的は、最も基本的なマシンでも、より複雑なマシンでも計算できることを示すことです。もちろん、チューリングマシンにさらに多くの機能(テープ、演算)を追加し続けることはできますが、そもそも同じ問題、つまり命令セットに同意しない人々が発生します。さらに、ランダムアクセスの欠如により、多くのアルゴリズムで大きなオーバーヘッドが発生します。
アルテリウス

0

仮定:高レベル言語L1を低レベル言語L0にコンパイルおよび最適化することは、高レベル言語L2(L1よりも高い)をL0にコンパイルおよび最適化するよりも簡単です。L2からL0へのコンパイルよりもL1からL0へのコンパイルの方が最適化されたコードを生成できるという意味で簡単です。

この仮定はおそらく正しいと思うので、ほとんどのコンパイラは低レベルの中間言語(IR / LLVM)を使用しているのでしょう。

これが当てはまる場合、低レベル言語L0を使用し、L0を他の低レベル言語に翻訳するコンパイラーを作成します。たとえば、MIPS命令セットを使用して、x86、arm、powerなどにコンパイルします。

-タウフィク


あなたの答えが本当かどうかわからないのですか?そしてそれをサポートできませんか?
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.