半䞖玀の「ナニバヌサル機械蚀語」1966〜2016幎過去、珟圚、未来

KDPV



過去



物語は1962幎にケンブリッゞ倧孊でCPL 「ケンブリッゞプログラミング蚀語」-ALGOL-60の「改良版」で䜜業が開始されたずきに開始できたす。 倧孊院生のマヌティン・リチャヌズがこの蚀語の研究に参加したした。 新しいYPを実装する際の䞻な困難は、さたざたなコンピュヌタヌプラットフォヌム甚にコンパむラヌを手動で移怍する必芁があるように思われたした。 特に、Cambridge EDSAC-2が Atlas -2に眮き換えられたずき、CPL開発者はコンパむラを新しいプラットフォヌムに移怍するのに倚くの時間を費やしたした。



Martinの論文は「自己コンパむル」CPL専甚でした。Martinによっお開発されたコンパむラは、CPLの非垞に単玔化されたバヌゞョンで蚘述され、そのコンパむラは圓時のマクロアセンブラで簡単に蚘述できたした。 CPLを新しいプラットフォヌムに移怍するには、次の2぀の手順を実行できたす。
  1. 「簡易CPL」コンパむラを手動で蚘述したす。
  2. 「フルCPL」のコンパむラをコンパむルしたす。


Martinはそこで止たらず、ポヌタブルコンパむラを開発するためのシステムであるBCPLを開発したした。 BCPLコンパむラは、Martin "OCODE"ず呌ばれる擬䌌コヌドを生成したした。

OCODEは次のようになりたした。
OCODE 「デコヌド」「プロコヌド」
 94 5 L1 83 73 69 86 69
 95 4
 42 0
 42 0 40 2 14
 83
 42 0 42 1 40 2 14 83
 42 2
 40 3 42 1 15
 92
 85 L5
 90 L6
 42 1 40 4 40 2 14 83
 40 4 42 1 14 80 4 
 90 5 40 4 40 5 88 L6
 91 4
 42 2 40 3 42 1 15 92
 85 L7
 90 L8 40 4 40 2 14
 8 87 L9
 40 4 42 2 11 92
 85 L11
 90 L10
 42 0 40 6 40 2 14 83
 40 4 40 6 14 80 6
 90 L11
 40 6 40 3 22 86 L10
 91 6 90 L9
 40 4 42 1 14 80 4
 90 L7 40 4 40 5 88 L8
 91 4 97 103 0
゚ントリ5 L1 'S' 'I' 'E' 'V' 'E'
セヌブ4
 LN 0
 LN 0 LP 2 PLUS
スティンド
 LN 0 LN 1 LP 2 PLUS STIND
 Ln 2
 LP 3 LN 1マむナス
店舗
ゞャンプL5
 LAB L6
 LN 1 LP 4 LP 2 PLUS STIND
 LP 4 LN 1 PLUS SP 4
 LAB L5 LP 4 LP 5 ENDFOR L6
スタック4
 LN 2 LP 3 LN 1マむナスストア
ゞャンプL7
 LAB L8 LP 4 LP 2 PLUS
 RV JF L9
 LP 4 LN 2マルチストア
ゞャンプL11
 LAB L10
 LN 0 LP 6 LP 2 PLUS STIND
 LP 4 LP 6 PLUS SP 6
 LAB L11
 LP 6 LP 3 LS JT L10
スタック6ラボL9
 LP 4 LN 1 PLUS SP 4
 LAB L7 LP 4 LP 5 ENDFOR L8
スタック4 RTRN゚ンドプロック0
; 手順のタむトル

; スタックフレヌム2぀のパラメヌタヌず2぀のロヌカル倉数

; スタックに番号0を眮きたす

; さらに0を入れ、2番目のスタック芁玠を远加したす

; スタックの䞀番䞊の配列にその䞋の倀を曞き蟌む

; 配列の最初の芁玠に぀いおも同じ

; スタックに2番を眮きたす

; 3番目のスタック芁玠の倀から1を匕く

; 結果をロヌカル倉数に曞き蟌みたす

; ラベルL5に移動

; ラベルタグL6

; スタックの4番目の芁玠を取埗し、このむンデックスで配列に曞き蟌みたす1

; スタック1の4番目の芁玠に远加し、結果を曞き戻したす

; L54番目のスタック芁玠<= 5番目の堎合、ラベルL6に移動

; スタック䞊に4぀の芁玠があるこずを発衚

; 3番目のスタック芁玠の倀から1を匕く

; ラベルL7に移動

; L8スタックの4番目ず2番目の芁玠を远加する

; このアドレスの倀を読み取りたす。 0の堎合、L9に進みたす

; 4番目の芁玠に2を掛けたす

; ラベルL11に移動

; タグラベルL10

; スタックの6番目の芁玠を取埗し、このむンデックス0で配列に曞き蟌みたす

; スタックの4番目の芁玠に4番目の芁玠を远加し、結果を曞き戻したす

; タグラベルL11

; スタックの7番目の芁玠が4番目よりも小さい堎合は、ラベルL10に移動したす

; スタックには6぀の芁玠がありたす。 タグラベルL9

; スタック1の4番目の芁玠に远加し、結果を曞き戻したす

; L104番目のスタック芁玠<= 5番目の堎合、L8に移動

; スタックには4぀の芁玠がありたす。 手順の終わり

スペヌスを節玄するために、コマンドシヌケンスは1行で蚘述されおいたす。MartinはBCPLマニュアルでもたったく同じこずを行っおいたす。



゜ヌスパッケヌゞBCPLをダりンロヌドしたす。

 LETふるいworkvec、vecsizeBE
 {
   workvec0= 0
   workvec1= 0
   FOR i = 2 to vecsize-1 DO workvecI= 1
   FOR i = 2 TO vecsize-1 DO
     IF workvecしたす
     {LET j = 2 * i
       j <vecsize DOの堎合
       {workvecj= 0
         j= j + i
       }
     }
 }
OCODEの新しいバヌゞョンでは、浮動小数点数のサポヌトが远加されそれぞれ、サポヌトされるオペコヌドのセットがほが2倍になりたした、 ENDFOR



オペコヌドがENDFOR



さENDFOR



-代わりに、 LE JT



ペアLE JT



生成されたす。



「ナニバヌサルマシン蚀語」の䞭で、OCODEは、そのラベルが特別な指瀺によっお決定されるずいう点でナニヌクです。 プログラムを解釈するには、たずすべおをメモリにロヌドし、その䞭のラベルを芋぀ける必芁がありたす。
-そしお、別のプログラムであるコヌドゞェネレヌタヌが 、このような擬䌌コヌドを含むファむルを最終プロセッサ甚の実行可胜プログラムに倉換したした。 OCODEは、スペヌスず改行で区切られた10進数のテキストファむルずしお保存されたした。OCODEの開発䞭、ファむル圢匏を特定のバむトサむズにリンクするず、そのようなファむルの移怍性が制限されたした。



BCPL 1コンパむラはOCODEずしお出荷されおおり、新しいプラットフォヌムに移怍するために必芁でした
  1. 擬䌌コヌドむンタヌプリタヌを手動で蚘述したす2 任意の蚀語、BASICでも。
  2. 3 BCPLで蚘述されたコヌドゞェネレヌタヌをプラットフォヌムに適合させたす。
  3. むンタヌプリタヌ2の䞋でBCPLコンパむラヌ1を実行し、コヌドゞェネレヌタヌ3にフィヌドし、コヌドゞェネレヌタヌの実行可胜ファむル4を取埗したす。
    • 通蚳者2は、今埌必芁ありたせん。
  4. コンパむラヌ擬䌌コヌド1をコヌドゞェネレヌタヌ4から远い出し、出力でコンパむラヌ実行可胜ファむルを取埗したす。




このアプロヌチは、コンパむラを新しいプラットフォヌムに移怍するために最䜎限の䜎レベルのプログラミングのみが必芁であるこずを意味しおいたした。 実際、BCPLの実装は1967幎たでに完了したした。数幎前に始たったCPLの実装が完了する前です



システムプログラミングに察するBCPLのメリットは、ケントンプ゜ンにむンスピレヌションを䞎えおBe蚀語を䜜成し、ケンの同僚であるデニスリッチヌにむンスピレヌションを䞎えおCを䜜成したした。 BCPLから䌝統が{



䞭括匧}



プログラムブロックを指定するようになり、BCPL で最初のプログラム「Hello、World」 が 䜜成されたした 。

 「libhdr」を取埗

 LET開始= VALOF
 {writef "Hello * n"
  結果0
 }
BCPLが歎史䞊ダりンした理由は私たちにずっおより重芁ですOCODEは最初の普遍的な「呜什セットアヌキテクチャ」 ISAです。 「仮想マシン」。その機胜により特定のハヌドりェアプラットフォヌムに関連付けられおいたせん。 したがっお、BCPLは、 「䞀床曞き蟌み、どこでも実行」  WORA  パラダむムに準拠する最初のプログラミング蚀語です。BCPLプログラムは、コンパむルされた圢匏で配垃でき、OCODEコヌドゞェネレヌタヌが存圚するプラットフォヌムで実行できたす。



BCPL自䜓ずそのOCODEは、英囜以倖では人気を博しおいたせんが、 WORAの考え方は定着しおいたす。 1974幎、すでに倧陞で、 ETHチュヌリッヒで 、ニクラりスノィルトの指導の䞋で、「Pascal-P」が開発されたした-䞭間「pコヌド」ぞのコンパむルず、この「pコヌド」の特定のハヌドりェアプラットフォヌム甚の実行可胜コヌドぞのコンパむル。 海掋の反察偎であるUCSDの Pascal-Pに基づいお、 p-System 1978OSが䜜成されたした。コヌドゞェネレヌタヌはたったくありたせんでした 。ベアメタルでの䜜業。 すべおのp-Systemシステムナヌティリティは、クロスプラットフォヌムのp-codeの圢匏で提䟛され、p-Systemを新しいハヌドりェアプラットフォヌムに適合させるには、p-codeむンタヌプリタヌを蚘述するだけで十分でした。



Pコヌドの䟋
 0000D8 p2_0SLDL 1
 000100 SLDC 0
 00029A STO
 000302 SLDC 2
 0004CC 03 STL 3
 0006DA p2_2SLDL 3
 000731 SLDC 49
 0008C8 LEQI
 0009A1 12 FJP p2_5
 000BD8 SLDL 1
 000CDA SLDL 3
 000D01 SLDC 1
 000E32 SLDC 50
 000F88 CHK
 001001 SLDC 1
 001195 SBI
 0012A4 01 IXA 1
 001401 SLDC 1
 00159A STO
 0016DA SLDL 3
 001701 SLDC 1
 001882 ADI
 0019CC 03 STL 3
 001BB9 F6 UJP p2_2
 001D02 p2_5SLDC 2
 001ECC 03 STL 3
 0020DA p2_4SLDL 3
 002131 SLDC 49
 0022C8 LEQI
 0023A1 2F FJP p2_1
 0025D8 SLDL 1
 0026DA SLDL 3
 002701 SLDC 1
 002832 SLDC 50
 002988 CHK
 002A01 SLDC 1
 002B95 SBI
 002CA4 01 IXA 1
 002EF8 SIND 0
 002FA1 1C FJP P2_6
 003102 SLDC 2
 0032DA SLDL 3
 00338F MPI
 0034CC 02 STL 2
 0036D9 p2_3SLDL 2
 003732 SLDC 50
 0038C9 LESI
 0039A1 12 FJP p2_6
 003BD8 SLDL 1
 003CD9 SLDL 2
 003D0​​1 SLDC 1
 003E32 SLDC 50
 003F88 CHK
 004001 SLDC 1
 004195 SBI
 0042A4 01 IXA 1
 004400 SLDC 0
 00459A STO
 0046D9 SLDL 2
 0047DA SLDL 3
 004882 ADI
 0049CC 02 STL 2
 004BB9 F4 UJP P2_3
 004DDA P2_6SLDL 3
 004E01 SLDC 1
 004F82 ADI
 0050CC 03 STL 3
 0052B9 F2 UJP p2_4
 0054AD 00 P2_1RNP 0
; 最初のパラメヌタヌをスタックにプッシュしたす

; スタックに0を眮きたす

; スタックの䞀番䞊の倀をその䞋のアドレスに曞き蟌みたす

; スタックに2番を眮きたす

; スタックの最䞊郚の倀をスタックフレヌムにロヌカル倉数に曞き蟌む

; ロヌカル倉数をスタックにプッシュしたす



; 49以䞋ですか

; そうでない堎合は、ラベルp2_5に移動したす









; 配列の境界を確認しおくださいロヌカル倉数3は1から50の間でなければなりたせん



; スタックの䞀番䞊の倀から1を匕く、぀たり ロヌカル倉数3から

; 配列芁玠ぞのポむンタを蚈算したすindex-前回の枛算結果、

; baseは最初のパラメヌタヌ、芁玠サむズは1ワヌド

; 蚈算ポむンタによるナニットの曞き蟌み





; ロヌカル倉数3の倀に1を远加したす

; 結果をスタックフレヌムに曞き戻す

; ラベルp2_2ぞの無条件ゞャンプ



; ロヌカル倉数番号3にデュヌスを曞き蟌む





; この倉数は49以䞋ですか

; そうでない堎合は、ラベルp2_1に移動したす









; 配列の境界を確認しおくださいロヌカル倉数3は1から50の間でなければなりたせん





; 䞊蚘ずたったく同じように、配列芁玠ぞのポむンタを蚈算したす

; 蚈算されたポむンタからオフセット0のワヌドを読み取りたす

; れロ倀が読み取られた堎合、ラベルp2_5に移動したす





; ロヌカル倉数3の倀に2を掛けたす

; スタックフレヌム内に結果を曞き蟌む





; この倀は50未満ですか

; そうでない堎合は、ラベルp2_6に移動したす









; 配列の境界を確認しおくださいロヌカル倉数2は1から50の間でなければなりたせん





; 配列芁玠ぞのポむンタを蚈算したすむンデックスは1぀少なくなりたす

; ロヌカル倉数2の倀、ベヌスおよびサむズ-䞊蚘のように

; 蚈算されたポむンタヌにれロを曞き蟌む





; ロヌカル倉数2に倉数3の倀を远加したす

; 結果をスタックフレヌムに曞き戻す

; ラベルp2_3ぞの無条件ゞャンプ





; ロヌカル倉数3の倀に1を远加したす

; 結果をスタックフレヌムに曞き戻す

; ラベルp2_4ぞの無条件ゞャンプ

; スタックから呌び出し偎プロシヌゞャに0の倀を返したす



゜ヌスパッケヌゞpascalをダりンロヌドしたす。

 const data_size = 50;
タむプdata_array =ブヌル倀の配列[1..data_size];

手続きふるいvar workvecdata_array;
 var i、j敎数;
始める
   workvec [1]= false;
   for i= 2 to data_size-1 do workvec [i]= true;
   for i= 2 to data_size-1 do
     workvec [i]の堎合、開始
       j= 2 * i;
      䞀方、j <data_sizeは開始したす
         workvec [j]= false;
         j= j + i;
      終わり
    終わり
終わり;
機械語敎数ず浮動小数点数のみをサポヌトするOCODEず比范しお、Pascalのpコヌドは、文字列、配列、「パック配列」芁玠サむズが1ワヌド未満など、はるかに倚様なデヌタ型をサポヌトしたす。蚘録、セットなど。 動的メモリ割り圓おも同様です。 もう1぀の重芁な違いは、プロシヌゞャの「䜜業スタック」ず、パラメヌタずロヌカル倉数を含む「スタックフレヌム」が分離されたこずです。



コンパクトなpコヌドの堎合、倚くの呜什には、小さく頻繁に䜿甚される匕数倀の「短瞮オペコヌド」がありたす。



p-Systemは非垞に人気がありたした。いく぀かのApple IIモデルず、元のIBM PC1981を含むいく぀かのIBMコンピュヌタヌがOSずしおp-Systemずずもに提䟛されたした。 1979幎から、Western Digitalはp-code実行がハヌドりェアに実装されたPascal MicroEngineミニコンピュヌタヌをリリヌスしたした。 したがっお、抜象的な「ナニバヌサルマシン蚀語」からのpコヌドは、実際のコンピュヌタヌの実際のマシン蚀語に倉わりたした。



p-Systemは90幎代にはすでに垂堎から姿を消しおいたが、1996幎にJames GoslingにJava仮想マシンの䜜成を促すこずに成功した。 「䞀床曞くだけで、どこでも実行できたす」人気の広告スロヌガンに倉わり、「ナニバヌサルマシン蚀語」 「バむトコヌド」 の実装が2぀の方向に䞊行しお開発されたした。



圓然のこずながら、「バむトコヌドプロセッサ」のどれも-PコヌドでもJavaでも-商業的に成功したせんでした。 これには、以前のIntel iAPX 432 1981プロセッサ、Adaのバむトコヌドのハヌドりェア実装も含たれたす。Javaバむトコヌド、Wirthのpコヌド、およびOCODEは、すべお䞭間指向であるため、すべおスタック指向です。生成ず解釈が最も簡単です。 「仮想マシン」スタックは制限されおいたせん。 反察に、「鉄」プロセッサには固定数のレゞスタがありたす。コンパむラの最も重芁なタスクの1぀は、メモリアクセスができる限り実行されないようにレゞスタ間でデヌタを分散するこずです。 「鉄」のデヌタ間の䟝存関係を远跡し、「鉄」レゞスタに埓っおデヌタを配垃し、「鉄」の制限に適合するようにデヌタぞのアクセスを再配眮するには、非垞に耇雑なメカニズムが必芁です。 同じレベルの半導䜓技術では、同じハヌドりェアで同じバむトコヌドを実行するよりも、単玔なISA甚のプロセッサを䜜成し、その䞊にバむトコヌド倉換を実装する方が効率的です。 䜕床も䜕床も、倢のようなIT起業家は、「ナニバヌサルマシン蚀語」を実際の蚀語に倉えるこずは、技術的には可胜ですが、商業的には芋蟌みがないず確信するようになりたした。



Javaバむトコヌドの䟋


 2a
なる
 3c
 2a
 03
 03
 54
 2a
 04
 03
 54
 05
 3d
 1c
 1b
 a2 00 0d
 2a
 1c
 04
 54
 84 02 01
 a7 ff f4
 05
 3d
 1c
 1b
 a2 00 23
 2a
 1c
 33
 99 00 17
 05
 1c
 68
 3e
 1d
 1b
 a2 00 0e
 2a
 1d
 03
 54
 1d
 1c
 60
 3e
 a7 ff f3
 84 02 01
 a7 ff de
 b1
プラむベヌト静的ボむドシヌブブヌル[];
 コヌド
     0aload_0 //むンデックス0のスタックフレヌムから取埗したリンクをスタックに配眮したす。 パラメヌタ
     1arraylength //枡された配列の長さをスタックにプッシュしたす
     2istore_1 //スタックから敎数をむンデックス1のスタックフレヌムに保存したす
     3aload_0       
     4iconst_0 //スタックに敎数を眮く-定数0
     5アむコン      
     6bastore //むンデックス0でバむトたたはブヌル配列0に曞き蟌む
     7aload_0       
     8iconst_1      
     9アむコン
    10bastore //同じ配列0にむンデックス1で曞き蟌む
    11iconst_2      
    12istore_2 //敎数倀2をむンデックス2のスタックフレヌムに保存したす
    13iload_2 //保存した倀をスタックに配眮したす
    14iload_1 //ロヌカル倉数番号1をスタックに配眮したす
    15if_icmpge 28 // 2぀の敎数を比范したす。  value> =倉数の堎合、呜什28に進みたす
    18aload_0       
    19iload_2       
    20iconst_1      
    21bastore //ロヌカル倉数のむンデックスにあるナニットをバむトたたはブヌル配列に曞き蟌む
    22iinc 2、1 //ロヌカル倉数2を1぀増やす
    25goto 13 //呜什13に移動
    28iconst_2      
    29istore_2 //ロヌカル倉数2に敎数2を曞き蟌む
    30iload_2       
    31iload_1
    32if_icmpge 67 //倉数番号2が倉数番号1以䞊の堎合、呜什67に進む
    35aload_0       
    36iload_2       
    37baload //この倉数からむンデックスによっおバむトたたはブヌル配列の芁玠を読み取りたす
    38ifeq 61 //読み取り項目がれロの堎合、呜什61に進みたす
    41iconst_2      
    42iload_2       
    43imul //ロヌカル倉数No. 2の倀に2を掛ける
    44istore_3 //結果をむンデックス3のスタックフレヌムに保存する
    45iload_3       
    46iload_1       
    47if_icmpge 61 //ロヌカル倉数3> =倉数1の堎合、呜什61に進む
    50aload_0       
    51iload_3       
    52アむコン      
    53bastore //倉数No. 3からのむンデックスによっおバむトたたはブヌル配列0に曞き蟌みたす
    54iload_3       
    55iload_2       
    56iadd //ロヌカル倉数No. 3倉数No. 2の倀に远加
    57istore_3 //結果をスタックフレヌムに曞き戻す
    58goto 45 //呜什45に移動
    61iinc 2、1 //ロヌカル倉数2を1぀増やす
    64goto 30 //呜什30に移動
    67return //プロシヌゞャから戻る


゜ヌスコヌド

  private static void sieve(boolean[] workvec) { int vecsize = workvec.length; workvec[0] = false; workvec[1] = false; for(int i = 2; i<vecsize; i++) workvec[i] = true; for(int i = 2; i<vecsize; i++) if(workvec[i]) { int j = 2 * i; while(j < vecsize) { workvec[j] = false; j = j + i; } } }
      
      





バむトコヌドはWirthのpコヌドよりもさらに蚭蚈されおおり、コンパクトに蚭蚈されおいたす。たずえば、 iflt



れロず条件SLDC 0; GEQI; FJP



比范は3぀の呜什SLDC 0; GEQI; FJP



察応しSLDC 0; GEQI; FJP



SLDC 0; GEQI; FJP



SLDC 0; GEQI; FJP



、およびiinc



は4぀のSLDL; SLDC; ADI; STL



呜什を眮き換えSLDL; SLDC; ADI; STL



SLDL; SLDC; ADI; STL



SLDL; SLDC; ADI; STL







ただし、反察の䟋がありたす。 新しいISAずそのコンパむラを䜜成し、新しいプラットフォヌムに必芁な最小限の゜フトりェアが珟れるのを埅぀よりも、既存のプログラムが新しいプロセッサで実行できるように、人気のISAを実装するこずはプロセッサメヌカヌにずっおはるかに有益です。 IA-32は長い間、このような「ナニバヌサルマシン蚀語」のたたでした。既存の゜フトりェアの量は、新しいISAぞの切り替えの利点を䞊回り、 Pentium Pro 1995以降、Intelプロセッサは本質的に叀いISAの「ハヌドりェア゚ミュレヌション」を実装したした。 8぀の「クラシック」レゞスタで動䜜するIA-32呜什は、プロセッサにより40の「鉄」レゞスタで動䜜する内郚RISCマむクロコマンドに倉換されたす。 プロセッサ内のパむプラむンは、これらのRISCマむクロコマンドをいく぀かのスレッドに実行したす-これがデヌタ間の䟝存関係を壊さない堎合、マむクロコマンドを任意に再配眮したす。 開発チヌムにLinus Torvaldsを含むTransmeta Crusoeプロセッサ 2000では、ISAハヌドりェア゚ミュレヌションのアむデアがさらに開発されたした。箱から出しおIA-32をサポヌトしたしたが、他のISAず連携するように再プログラムできたす-これを実蚌するためにTransmetaには、ハヌドりェアJavaバむトコヌドをサポヌトするCrusoeの「広告サンプル」がありたした。



IA-32マシンコヌドの䟋
機械コヌド アセンブラヌ



 55
 89 e5
 56
 66 c7 01 00 00
 b8 02 00 00 00
 02 00 00 00
 eb 05

 c6 04 31 01
 46

 39 d6
 7c f7
 eb 01

 40

 39 d0
 7d 17

 80 3c 01 00
 74 f5

 8d 34 00
 eb 06

 c6 04 31 00
 01 c6

 39 d6
 7c f6
 eb e4

 5e
 5d
 c3
	 .type _ZL5sievePbi、@関数
 _ZL5sievePbiecxに枡される配列ぞのポむンタヌ、edxぞの配列の長さ
 ゚ントリ
	 pushlebp以前のebp倀を保持
	 movlesp、ebpebpは珟圚のスタックフレヌムを指すようになりたした
	 pushlesi以前のesi倀を保持
	 movw $ 0、ecxecxにれロワヌドを曞き蟌む
	 movl $ 2、eax぀たり、配列の2぀の芁玠が1぀の呜什でリセットされたす
	 movl $ 2、esieaxずesiで2぀節玄
	 jmp .LBB1_1ラベル.LBB1_1に移動
 .LBB1_2for.body
	 movb $ 1、ecx、esiecx + esiにシングルバむトを曞き蟌む
	 inclesiesiを1぀増やしたす
 .LBB1_1.for.cond
	 cmpledx、esiesiずedxを比范
	 jl .LBB1_2edx <esiの堎合、ラベル.LBB1_2に移動
	 jmp .LBB1_4それ以倖の堎合、ラベル.LBB1_4に移動
 .LBB1_3for.inc.11
	 incleaxeaxを1぀増やしたす
 .LBB1_4.for.cond.4
	 cmpledx、eaxeaxずedxを比范
	 jge .LBB1_9edx> = esiの堎合、ラベル.LBB1_9に移動
 for.body.7
	 cmpb $ 0、ecx、eaxecx + esiでれロバむトず比范
	 je .LBB1_3れロの堎合、.LBB1_3に移動
 if.then
	 lealeax、eax、esieaxの二重倀をesiに曞き蟌む
	 jmp .LBB1_7ラベル.LBB1_7に移動
 .LBB1_8while.body
	 movb $ 0、ecx、esiれロバむトをecx + esiに曞き蟌む
	 addleax、esieaxをesiに远加
 .LBB1_7while.cond
	 cmpledx、esiesiずedxを比范
	 jl .LBB1_8edx <esiの堎合、ラベル.LBB1_8に移動
	 jmp .LBB1_3それ以倖の堎合、ラベル.LBB1_3に移動
 .LBB1_9for.cond.cleanup.6
	 poplesi叀いesi倀を埩元
	popl %ebp #    ebp
	retl #   
, , .


「ナニバヌサルマシン蚀語」のハヌドりェア実装のこれたでのずころ成功した䟋で、実装されたISAがスタックされずに登録されたこずは偶然ではありたせん。 OCODEを眮き換えるために、Martin Richards自身がINTCODE1972ず呌ばれる新しいレゞストリuni-ISAを開発したした。 INTCODEは非垞にシンプルです。6぀のレゞスタ、8぀の操䜜、およびいく぀かのアドレッシングモヌドがサポヌトされおいたす。呜什は、アドレス指定モヌドに応じお、1ワヌドたたは2ワヌドを占有したす。 1980幎に、Martinは16ビットマむコン甚のこのuni-ISAのバヌゞョンを開発したした。新しいuni-ISA-ただ6぀のレゞスタがありたすが、より耇雑で盎亀性の䜎いコマンドセットがありたす-はCintcodeず呌ばれ、非垞にコンパクトでした。広告リヌフレットで承認されたしたCintcodeプログラムは、通垞、6502マシンコヌドにコンパむルされるよりも3倍少ないメモリを䜿甚したす。コンピュヌタヌの堎合、BBC MicroおよびAmigaは、マシンコヌドずずもにCintcodeの実行をサポヌトする䞀般的なOSでした。



Cintcodeの䟋
P



— ; P[3]



, P[4]



— .



 0: 10 L0 ; A := 0
 1: DB ST0P3 ; P[3][0] := A (   )
 2: DD ST1P3 ; P[3][1] := A (   )
 3: 0F LM1 ; A := -1
 4: C4 AP4 ; A := A + P[4] (    )
 5: A6 SP6 ; P[6] := A (   )
 6: 12 L2 ; B := A; A := 2
 7: A5 SP5 ; P[5] := A
 8: 5C0A JLS 10 ; IF B<A GOTO 19
10: 11 L1 ; A := 1
11: 83 LP3 ; B := A; A := P[3]
12: 9A STP5 ; P[5][A] := B (     P[5])
13: B5 XCH ; A := B
14: C5 AP5 ; A := A + P[5]
15: A5 SP5 ; P[5] := A (  P[5]  )
16: 86 LP6 ; B := A; A := P[6]
17: 9CF8 JLE -8 ; IF B<=A GOTO 10
19: 0F LM1 ; A := -1
20: C4 AP4 ; A := A + P[4]
21: A6 SP6 ; P[6] := A (     )
22: 12 L2 ; B := A; A := 2
23: A5 SP5 ; P[5] := A
24: 5C1B JLS 27 ; IF B<A GOTO 52
26: 83 LP3 ; A := P[3]
27: D8 RVP5 ; A := P[5][A] (     P[5])
28: 1E11 JEQ0 17 ; IF A=0 GOTO 46
30: 85 LP5 ; A := P[5]
31: 12 L2 ; B := A; A := 2
32: 34 MUL ; A := A * B (  P[5])
33: A7 SP7 ; P[7] := A
34: 84 LP4 ; B := A; A := P[4] ( A  )
35: BC0A JGE 10 ; IF B>=A GOTO 46
37: 10 L0 ; A := 0
38: 87 LP7 ; B := A; A := P[7]
39: 98 STP3 ; P[3][A] := B (     P[7])
40: 87 LP7 ; A := P[7]
41: C5 AP5 ; A := A + P[5]
42: A7 SP7 ; P[7] := A (  P[7]  P[5])
43: 84 LP4 ; B := A; A := P[4] ( A  )
44: 5CF8 JLS -8 ; IF B<A GOTO 37
46: 11 L1 ; A := 1
47: C5 AP5 ; A := A + P[5]
48: A5 SP5 ; P[5] := A (  P[5]  )
49: 86 LP6 ; B := A; A := P[6] (A  1   )
50: 9CE7 JLE -25 ; IF B<=A GOTO 26
52: 7B RTN


(2014) BCPL Cintcode System BCPL. Cintcode ( A B ) ( A ).




積み重ねられたuni-ISAの開発の頂点は、たたは、反察偎から芋るず、開発の行き止たりです。MSIL2001;正匏にCILず呌ばれおいたすです。MSILはJavaバむトコヌドに非垞に䌌おいたすが、いく぀かの远加機胜を远加したす。私の知る限り、ハヌドりェアにMSILを実装する詊みは行われおいたせん。マむクロ゜フトは、クロスプラットフォヌムでフル機胜のWebアプリケヌションを䜜成するためのJavaの代替案を提案しようずもしおいたせん。MSILは「Microsoftプラットフォヌムのマシン蚀語」のたたであり、他にはありたせん。



MSILの䟋
.method private hidebysig static
        void sieve(bool[] workvec) cil managed
 {
  .maxstack 3
  .locals init ([0] int32 vecsize,
                [1] int32 i,
                [2] int32 V_2,
                [3] int32 j)
  IL_0000: /* 02 | */ ldarg.0 //     №0 ()
  IL_0001: /* 8E | */ ldlen //    ( )
  IL_0002: /* 69 | */ conv.i4 //    int32 (  )
  IL_0003: /* 0A | */ stloc.0 //      №0
  IL_0004: /* 02 | */ ldarg.0 //    
  IL_0005: /* 16 | */ ldc.i4.0 //     0 (  )
  IL_0006: /* 16 | */ ldc.i4.0
  IL_0007: /* 9C | */ stelem.i1 //        
  IL_0008: /* 02 | */ ldarg.0
  IL_0009: /* 17 | */ ldc.i4.1 //     1 (  )
  IL_000a: /* 16 | */ ldc.i4.0
  IL_000b: /* 9C | */ stelem.i1 //     (int8)    1
  IL_000c: /* 18 | */ ldc.i4.2
  IL_000d: /* 0B | */ stloc.1 //      №1
  IL_000e: /* 2B | 08 */ br.s IL_0018 //      IL_0019
  IL_0010: /* 02 | */ ldarg.0
  IL_0011: /* 07 | */ ldloc.1 //      
  IL_0012: /* 17 | */ ldc.i4.1
  IL_0013: /* 9C | */ stelem.i1 //        
  IL_0014: /* 07 | */ ldloc.1
  IL_0015: /* 17 | */ ldc.i4.1
  IL_0016: /* 58 | */ add //      
  IL_0017: /* 0B | */ stloc.1 //     
  IL_0018: /* 07 | */ ldloc.1
  IL_0019: /* 06 | */ ldloc.0 //      №0
  IL_001a: /* 32 | F4 */ blt.s IL_0010 //   №1 <  №0,   IL_0010
  IL_001c: /* 18 | */ ldc.i4.2
  IL_001d: /* 0C | */ stloc.2 //      №2
  IL_001e: /* 2B | 1B */ br.s IL_003b //      IL_003b
  IL_0020: /* 02 | */ ldarg.0
  IL_0021: /* 08 | */ ldloc.2
  IL_0022: /* 90 | */ ldelem.i1 //       
  IL_0023: /* 2C | 12 */ brfalse.s IL_0037 //    ,   IL_0037
  IL_0025: /* 18 | */ ldc.i4.2
  IL_0026: /* 08 | */ ldloc.2
  IL_0027: /* 5A | */ mul //     №2  
  IL_0028: /* 0D | */ stloc.3 //      №3
  IL_0029: /* 2B | 08 */ br.s IL_0033 //      IL_0033
  IL_002b: /* 02 | */ ldarg.0
  IL_002c: /* 09 | */ ldloc.3
  IL_002d: /* 16 | */ ldc.i4.0
  IL_002e: /* 9C | */ stelem.i1 //  0       №3
  IL_002f: /* 09 | */ ldloc.3
  IL_0030: /* 08 | */ ldloc.2
  IL_0031: /* 58 | */ add //     №2  №2
  IL_0032: /* 0D | */ stloc.3 //     №2
  IL_0033: /* 09 | */ ldloc.3
  IL_0034: /* 06 | */ ldloc.0
  IL_0035: /* 32 | F4 */ blt.s IL_002b //   №3 <  №0,   IL_002b
  IL_0037: /* 08 | */ ldloc.2
  IL_0038: /* 17 | */ ldc.i4.1
  IL_0039: /* 58 | */ add //      №2
  IL_003a: /* 0C | */ stloc.2 //     
  IL_003b: /* 08 | */ ldloc.2
  IL_003c: /* 08 | */ ldloc.0
  IL_003d: /* 32 | E1 */ blt.s IL_0020 //   №2 <  №0,   IL_0020
  IL_003f: /* 2A | */ ret //   
 }


C# Java boolean



→ bool



. Java- MSIL : -, , . -, (/ , , ..), MSIL, add



, «», .. ; (, — int32) . , MSIL JIT-, MSIL- .



, MSIL «», iflt



iinc



.



この千幎玀には、「ナニバヌサルマシン蚀語」に察するスタックの競合はなくなりたした。



プレれント



2000幎、UIUCの倧孊院生であるChris Luttner は卒業プロゞェクトずしお、Javaのコヌドを普遍的な「䞭間衚珟」IRに倉換する完党に独立した「フロント゚ンド」で構成される「ナニバヌサルコンパむラ」LLVMの開発を開始したした。バック゚ンド。IRを特定のISAの実行可胜コヌドに倉換したす。䞭間衚珟LLVM-IRずしお、単䞀の割り圓おフォヌムが遞択されたした「SSAフォヌム」

各倉数には倀が1回割り圓おられ、プログラムの動䜜䞭は倉曎されたせん。このフォヌムは、デヌタ間の䟝存関係の远跡を簡玠化し、個々の呜什の眮換ず眮換、重耇たたは「デッド」呜什の怜出ず削陀などを単玔化したす。



LLVM-IRの䟋
(BB), ( ). BB . — . BB , .. BB, .



 ; Function Attrs: minsize noinline nounwind optsize
define internal fastcc void @_ZL5sievePbi(i8* nocapture %workvec, i32 %vecsize) #0 {
 ; #0 --     (  )
entry:
  store i8 0, i8* %workvec, align 1, !tbaa !1 ;      
  %arrayidx1 = getelementptr inbounds i8, i8* %workvec, i32 1 ;      
  store i8 0, i8* %arrayidx1, align 1, !tbaa !1 ;      
  br label %for.cond ;     BB

for.cond: ; preds = %for.body, %entry
  %i.0 = phi i32 [ 2, %entry ], [ %inc, %for.body ]
 ; %i.0   2,    BB   %entry,   %inc,    %for.body
  %cmp = icmp slt i32 %i.0, %vecsize
 ;  %i.0  %vecsize   ,    %cmp  1  0
  br i1 %cmp, label %for.body, label %for.cond.4 ;    %for.body  %for.cond.4

for.body: ; preds = %for.cond
  %arrayidx2 = getelementptr inbounds i8, i8* %workvec, i32 %i.0 ;    %i.0-  
  store i8 1, i8* %arrayidx2, align 1, !tbaa !1 ;      
  %inc = add nuw nsw i32 %i.0, 1 ;  %inc  %i.0  
 ; nuw  nsw ,     (  ),    
  br label %for.cond ;     BB

for.cond.4: ; preds = %for.cond, %for.inc.11
  %i3.0 = phi i32 [ %inc12, %for.inc.11 ], [ 2, %for.cond ]
 ; %i3.0   2,    BB   %for.body,   %inc12,   %for.inc.11
  %cmp5 = icmp slt i32 %i3.0, %vecsize ;  %i3.0  %vecsize   
  br i1 %cmp5, label %for.body.7, label %for.cond.cleanup.6 ;  ,  %i3.0  %vecsize

for.cond.cleanup.6: ; preds = %for.cond.4
  ret void ;   ,   

for.body.7: ; preds = %for.cond.4
  %arrayidx8 = getelementptr inbounds i8, i8* %workvec, i32 %i3.0
  %0 = load i8, i8* %arrayidx8, align 1, !tbaa !1, !range !5 ;       %i3.0
  %tobool = icmp eq i8 %0, 0 ;      
  br i1 %tobool, label %for.inc.11, label %if.then

if.then: ; preds = %for.body.7
  %mul = shl nsw i32 %i3.0, 1 ;  %mul   %i3.0
  br label %while.cond ;     BB

while.cond: ; preds = %while.body, %if.then
  %j.0 = phi i32 [ %mul, %if.then ], [ %add, %while.body ]
  %cmp9 = icmp slt i32 %j.0, %vecsize ;  %j.0  %vecsize   
  br i1 %cmp9, label %while.body, label %for.inc.11 ;  %j.0 < %vecsize,   %while.body

while.body: ; preds = %while.cond
  %arrayidx10 = getelementptr inbounds i8, i8* %workvec, i32 %j.0
  store i8 0, i8* %arrayidx10, align 1, !tbaa !1 ;    %j.0-  
  %add = add nsw i32 %j.0, %i3.0 ;  %add  %j.0  %i3.0
  br label %while.cond ;     BB

for.inc.11: ; preds = %while.cond, %for.body.7
  %inc12 = add nuw nsw i32 %i3.0, 1 ;  %inc12  %i3.0  
  br label %for.cond.4
 }


IA-32 LLVM IR — , , , BB .



!tbaa !1



— alias analysis ; !range !5



— ( bool



— 0 1).



, — «» MSIL.



C++:

 static void sieve(bool workvec[], int vecsize) { workvec[0] = false; workvec[1] = false; for(int i = 2; i<vecsize; i++) workvec[i] = true; for(int i = 2; i<vecsize; i++) if(workvec[i]) { int j = 2 * i; while(j < vecsize) { workvec[j] = false; j = j + i; } } }
      
      





LLVM-IRは、ナニISAずしおではなく、䞻にフロント゚ンドからバック゚ンドにコヌドを転送するための効果的な方法ずしお開発されたため、ナニISAの圹割には倚くの欠点がありたす。たず、タヌゲットプラットフォヌムの機胜がLLVM-IRの生成に圱響する可胜性がありたす。32ビットシステム甚のプログラムは、64ビットシステム甚のプログラムずは別のLLVM-IRにコンパむルされたす。たた、Windows甚のプログラムは、Linux甚のプログラムずは異なるLLVM-IRでコンパむルされたす。次に、LLVM-IRは䞍安定です。LLVM開発者は、重芁なプラットフォヌムで重芁な蚀語ツヌルをより効率的にコンパむルできる堎合、新しい呜什を远加したり、既存の呜什の倀を倉曎したりできたす。これは、特定のバヌゞョンのフロント゚ンドによっお生成されたLLVM-IRは、察応するバヌゞョンのバック゚ンドでのみ䜿甚でき、他のバヌゞョンでは䜿甚できないこずを意味したす。第䞉に、LLVM-IRでは、コヌドに「未定矩の動䜜」を提瀺できたす-各バック゚ンドには、プログラムから最倧限のパフォヌマンスを「絞り出す」ために、䟿利な方法でそのようなコヌドをブロヌドキャストする暩利がありたす。 CたたはC ++で未定矩の動䜜を䌎うコヌドは、通垞、LLVM-IRで未定矩の動䜜を䌎うコヌドにコンパむルされたす。実際、このようなコヌドのセマンティクスは、特定のプラットフォヌムに最適な方法で、フロント゚ンドではなくバック゚ンドによっお決定されたす。圓然のこずながら、未定矩の動䜜を䌎うコヌドは、uni-ISAが昇栌される「1回曞き蟌み、どこでも実行」ずいうパラダむムず矛盟したす。それにもかかわらず、LLVMのアクティブな開発者の1人であるGoogleは、LLVMがサポヌトする倚くのPLのいずれかで曞かれたクロスプラットフォヌムアプリケヌションの配垃にLLVM-IRが適切な圢匏であるず考えたした。バヌゞョン312013以降、Google ChromeにはPNaClのサポヌトが含たれおいたす-LLVM-IRのサブセットで、安定した呜什セマンティクスを備えおおり、プラットフォヌム固有の構成ず最適化はありたせん。



15幎前にたったく同じ目的でクロスプラットフォヌムのフル機胜Webアプリケヌションを䜜成するために発明されたJavaアプレットよりもPNaClアプリケヌションの方が優れおいるのはなぜでしょうか。 このトピックの冒頭のKDPVはたさにトピックです。私はPNaClの2぀の利点を知っおいたす。たず、Javaスタックバむトコヌドず比范したLLVM-IRは、ブラりザヌがPNaClアプリケヌションを特定のタヌゲットプラットフォヌムのマシンコヌドに倉換するずきのコヌド最適化を簡玠化したす。 2番目の、そしお私が理解するように、䞻な議論はLLVMのオヌプン性ずラむセンスされた枅朔さです。そのホストSunずOracleはJavaサポヌトに関しおGoogleを含む圌らが出䌚ったすべおの人を蚎えたした。察照的に、LLVMずそのIRは完党にオヌプンです。そしお䞀方では、GoogleはPNaClコンパむラであらゆる皮類のパンず他のLLVM開発参加者によっお実装された新しい最適化で無料で受け取りたす。䞀方、他の開発者は、ブラりザにPNaClアプリケヌションのサポヌトを远加する暩利があり、蚎蚟を恐れるこずはありたせん。



これたでのずころ、Googleの䟋に埓っおPNaClのサポヌトを実装する意思はありたせんでした。それどころか、同じ目的のためのMozilla-クロスプラットフォヌムでフル機胜のWebアプリケヌションを䜜成する-は、asm.js2013ず呌ばれる独自のuni-ISAを開発したした。Asm.js生成は、LLVMの新しいバック゚ンドずしお実装されたした。 asm.jsずPNaClの䜜業はほが同時に行われ、Google Chromeではasm.jsのサポヌトはPNaClのサポヌトよりも早く登堎したした-バヌゞョン282013以降。



asm.jsは非垞に掗緎されたアむデアを実装しおいたす。そのプログラムはJavaScriptの倧幅に削陀された正しいコヌドです。したがっお、このようなプログラムはJavaScriptをサポヌトするブラりザヌで動䜜するはずです。䞀方、asm.jsコンストラクトを認識し、タヌゲットプラットフォヌムのマシンコヌドにオンザフラむでコンパむルできるブラりザは、JavaScriptを「額で」実行するブラりザよりも䜕倍も高速にプログラムを実行したす。したがっお、䞡方の叀いブラりザはasm.jsで新しいコヌドを実行でき、新しいブラりザは「クラシック」JavaScriptで叀いコヌドを実行できたす。スクリプト"use asm";



にプロロヌグがない堎合、「叀い方法で」実行されたす。



Asm.jsの䟋
C++, , Emscripten:



 function __ZL5sievePbi($workvec,$vecsize) { $workvec = $workvec|0; //      |0 $vecsize = $vecsize|0; var $0 = 0, $1 = 0, $10 = 0, $11 = 0, $12 = 0, $13 = 0, $14 = 0, $15 = 0, $16 = 0, $17 = 0, $18 = 0, $19 = 0, $2 = 0, $20 = 0, $21 = 0, $22 = 0, $23 = 0, $24 = 0, $25 = 0, $26 = 0; var $27 = 0, $28 = 0, $29 = 0, $3 = 0, $30 = 0, $31 = 0, $32 = 0, $33 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0, $i = 0, $i1 = 0, $j = 0, label = 0, sp = 0; sp = STACKTOP; STACKTOP = STACKTOP + 32|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort(); $0 = $workvec; $1 = $vecsize; $2 = $0; HEAP8[$2>>0] = 0; //       >>0 $3 = $0; $4 = ((($3)) + 1|0); //      HEAP8[$4>>0] = 0; $i = 2; while(1) { $5 = $i; $6 = $1; $7 = ($5|0)<($6|0); //     if (!($7)) { break; } $8 = $i; $9 = $0; $10 = (($9) + ($8)|0); HEAP8[$10>>0] = 1; $11 = $i; $12 = (($11) + 1)|0; $i = $12; } $i1 = 2; while(1) { $13 = $i1; $14 = $1; $15 = ($13|0)<($14|0); if (!($15)) { break; } $16 = $i1; $17 = $0; $18 = (($17) + ($16)|0); $19 = HEAP8[$18>>0]|0; //     $20 = $19&1; L8: do { if ($20) { $21 = $i1; $22 = $21<<1; $j = $22; while(1) { $23 = $j; $24 = $1; $25 = ($23|0)<($24|0); if (!($25)) { break L8; } $26 = $j; $27 = $0; $28 = (($27) + ($26)|0); HEAP8[$28>>0] = 0; $29 = $j; $30 = $i1; $31 = (($29) + ($30))|0; $j = $31; } } } while(0); $32 = $i1; $33 = (($32) + 1)|0; $i1 = $33; } STACKTOP = sp;return; }
      
      





興味深いこずに、開発䞭のasm.jsがJavaScriptの制限64ビット数、マルチスレッド、SIMD呜什などのサポヌトの欠劂に「遭遇」した堎合、欠萜しおいる構造がJavaScript暙準に远加されたした。したがっお、asm.jsず暙準JavaScriptずの互換性は、asm.js開発者だけでなく、蚀語暙準開発者の努力の結果です。



すでに述べた理由に加えお、Javaアプレットを䜿甚しおLLVMに基づく新しいテクノロゞヌを䜿甚する代わりに、asm.jsサポヌタヌは次の匕数を提䟛したす。「JavaScriptには仮想マシンが組み蟌たれおいるため、もう1぀远加するず、接続APIの2番目のセットが衚瀺され、DOM、ネットワヌク、センサヌ、入力デバむスなどに仮想マシンがアクセスできるようになりたす。このために䜕かを犠牲にしなければなりたせん。たずえば、仮想マシンのプロセスは、利甚可胜なリ゜ヌスをどのように分散したすかこの質問に答えるのは思ったより難しいです。」 オリゞナルのスペル特に、これぱンゞンの新機胜がasm.jsず「クラシック」JavaScriptから同時に利甚できるこずを意味したす。2回実装する必芁はありたせん。



未来



GoogleずAppleが䟝存しおいた生のLLVM-IRず比范しお、asm.jsには倚くの利点がありたす。しかし、欠点もありたす。たず、asm.jsのコヌドのサむズは非垞に倧きくなっおいたす。2぀の敎数を远加するず20バむト以䞊かかりたす。第二に、asm.jsコヌドを実行するには、再解析する必芁がありたす。JavaScript構文を䜿甚しおコヌドからコヌドを生成し、このコヌドからASTを埩元するのではなく、ASTの圢匏でコンパむルの結果を保存する方がはるかに効率的です。そのため、2015幎の倏に、WebAssemblyずいう新しい「ナニバヌサルマシン蚀語」が登堎したした。asm.jsの長所の䞀郚JavaScript゚ンゞンずの統合などを保持し、2぀の欠点を解消し、叀いJavaScript゚ンゞンずの盎接の互換性を拒吊したしたvsbのコメント、たたは、ブラりザでゲヌムがたったく起動しなかったため、たたは、1 fpsで始たりたした-違いはありたせん、ずにかく再生できたせん。」代わりに、WebAssembly開発者は「パテ」 -WebAssemblyでコヌドを読み取り、その堎でコヌドを生成するJavaScriptラむブラリ叀兞的な「asm.js; そしお圌の叀いバヌゞョンのブラりザはすでに実行方法を知っおいたす。



WebAssemblyの䟋
C++, , WebAssembly LLVM:



_Z5sievePbi:
	.param i32 #    $0  $1
	.param i32
	.local i32, i32, i32, i32 #    $2, $3, $4, $5
# %entry
	block BB0_9 #       --   
	i32.const $2, 0 #     
	i32.store8 $0, $2 #     
	i32.const $3, 1
	i32.add $push0, $0, $3 #    --  
	i32.store8 $pop0, $2 #     
	i32.const $4, 2
	set_local $5, $4
BB0_1: # %for.cond
	loop BB0_3
	i32.ge_s $push1, $5, $1 #    -- 
	br_if $pop1, BB0_3
# %for.body
	i32.add $push7, $0, $5 # $pushN  $popN -- ""  
	i32.store8 $pop7, $3 #    ( )
	i32.add $5, $5, $3 #     
	br BB0_1
BB0_3: # %for.cond.4
	loop BB0_9
	block BB0_8
	block BB0_4
	block BB0_3 #    ,   (? ?)
	i32.lt_s $push2, $4, $1
	br_if $pop2, BB0_4
	br BB0_9
BB0_4: # %for.body.7
	i32.add $push3, $0, $4
	i32.load8_u $5, $pop3 #       $4
	i32.eq $push4, $5, $2 #    
	br_if $pop4, BB0_8
# %if.then
	i32.shl $5, $4, $3 #  $4   , .. 
BB0_6: # %while.cond
	loop BB0_8
	i32.ge_s $push5, $5, $1
	br_if $pop5, BB0_8
# %while.body
	i32.add $push6, $0, $5
	i32.store8 $pop6, $2
	i32.add $5, $5, $4
	br BB0_6
BB0_8: # %for.inc.11
	i32.add $4, $4, $3
	br BB0_3
BB0_9: # %for.cond.cleanup.6
	return


LLVM-IR IA-32, ; WebAssembly , .



, , VEG - — « WebAssembly .» — .


GoogleはWebAssemblyの䞻芁な開発者の1぀になりたした-LLVMに基づいた新しい「ナニバヌサルマシン蚀語」では、PNaClの開発䞭に埗られたすべおの経隓が考慮されたす。圌らは自分でPNaClを開発する぀もりはありたせん。もう1぀の䞻芁な開発者であるMozillaは、asm.jsずは異なり、WebAssemblyが構文的にも意味的にも特定のPLに接続されおいないこずを匷調しおいたす。 10幎か2幎でJavaScriptが忘华の察象になり、ブラりザヌは゜ヌスコヌドのスクリプトをサポヌトしなくなりたす。代わりに、WebAssemblyはブラりザヌのWebアプリケヌションのネむティブ圢匏になりたす。゜フトりェア開発者が耇数ペヌゞのリストをBASICずPascalに配垃から実行可胜コヌドの配垃に切り替えた1980幎代に、PCプログラムはこの「飛躍的な進歩」を遂げたした。少なくずも「これをすべおコンパむルしお実行するにはどうすればよいか」ずいうレベルで、単䞀のプログラミング蚀語を知らなくおもPCを䜿甚できるようになりたした。

ほずんどのWebアプリケヌションナヌザヌは、JavaScriptに぀いおはたったく知りたせん。では、Webアプリケヌションを゜ヌスコヌドずしお配垃する意味は䜕ですか



モバむル機噚メヌカヌが埩掻したした。ハヌドりェアに新しい「ナニバヌサルマシン蚀語」でコヌドを実装するず、モバむルデバむスを取埗するためにWebアプリケヌションのパフォヌマンスが倧幅に向䞊する可胜性がありたす。 WebAssemblyは、高レベルの機械語ですが、スタック蚀語ではありたせん。したがっお、そのハヌドりェア実装は、スタックされたuni-ISAを実装する以前の詊みよりも成功する可胜性がありたす。最も重芁なこずは、x86が圓時のPCの䞖界を倉えたように、すべおのモバむルアプリケヌション甚の単䞀の機械語で゚コシステム党䜓を倉えるこずができるこずです。 「x86芇暩」以前は、PC向けのプログラムは、さたざたなプラットフォヌムで倚かれ少なかれ互換性のあるバヌゞョンでリリヌスされおいたした。たずえば、Prince of Persiaは、Amiga、Amstrad、Apple II、Atari、FM Towns、IBM PC、Macintosh Quadra、NEC PC-9801、SAMCoupé、Sharp X68000。しかし、ある時点から「PC甚プログラム」ずいうフレヌズは「x86甚プログラム」を意味し始めたした。同様に、「単䞀のモバむルISA」は、゜フトりェア開発者、デバむスメヌカヌOEM、およびプロセッサメヌカヌのリンクを解陀したす。OEMは、デバむスに任意のメヌカヌのプロセッサを遞択できたす。メヌカヌ;開発者は、異なるプラットフォヌム間でアプリケヌションを転送するためにお金を費やす必芁がなくなりたす。最終的に、必芁なプログラムのいずれかが自分のデバむスで起動されるず、ナヌザヌが勝ちたす。同様に、「単䞀のモバむルISA」は、゜フトりェア開発者、デバむスメヌカヌOEM、およびプロセッサメヌカヌのリンクを解陀したす。OEMは、デバむスに任意のメヌカヌのプロセッサを遞択できたす。メヌカヌ;開発者は、異なるプラットフォヌム間でアプリケヌションを転送するためにお金を費やす必芁がなくなりたす。最終的に、必芁なプログラムのいずれかが自分のデバむスで起動されるず、ナヌザヌが勝ちたす。同様に、「単䞀のモバむルISA」は、゜フトりェア開発者、デバむスメヌカヌOEM、およびプロセッサメヌカヌのリンクを解陀したす。メヌカヌ;開発者は、異なるプラットフォヌム間でアプリケヌションを転送するためにお金を費やす必芁がなくなりたす。最終的に、必芁なプログラムのいずれかが自分のデバむスで起動されるず、ナヌザヌが勝ちたす。開発者は、異なるプラットフォヌム間でアプリケヌションを転送するためにお金を費やす必芁がなくなりたす。最終的に、必芁なプログラムのいずれかが自分のデバむスで起動されるず、ナヌザヌが勝ちたす。開発者は、異なるプラットフォヌム間でアプリケヌションを転送するためにお金を費やす必芁がなくなりたす。最終的に、必芁なプログラムのいずれかが自分のデバむスで起動されるず、ナヌザヌが勝ちたす。



䞀方、単䞀の機械語はプロセッサメヌカヌに厳栌なフレヌムワヌクを課したす。「シングルISA」に受け入れられ、他のメヌカヌによっお実装されるたで、新しい機胜を新しいプロセッサに远加するこずはできたせん。さらに、統䞀された機械語の開発により、メヌカヌの1぀が蚀語に特に有益な機胜を蚀語にプッシュしようずするず、状況は避けられたせん。たずえば、Intelプロセッサの敎数陀算呜什は、れロで陀算するずきに䟋倖をスロヌしたす。 ARMプロセッサで-結果ずしおれロを返したす。ARM゚ンゞニアは、陀​​数テストをコンパむラにシフトし、陀数が意図的にれロでない堎合に陀算を高速化する方が良いず考えたした。第䞉に、グラフィックスのサポヌトはどうですか WebAssembly は詊しおさえいたせんGPUに察しお単䞀のISAを提䟛したす-異なるメヌカヌの奜みの違いは、IntelずARMのコマンドシステム間よりもさらに倧きくなりたす。



ただし、これらの考慮事項はすべお、WebAssemblyが根付くずいう事実に基づいおおり、PNaClのように数幎埌には攟棄されず、JavaやMSILのような別のニッチで隔離されるこずはありたせん。



芋おみたしょう。



All Articles