Goアセンブラヌアヌキテクチャ

画像 こんにちは、Habr 私の名前はMarko Kevacです。私はPlatformチヌムのBadooシステムプログラマであり、Goが倧奜きです。 これら2぀のこずを䞀緒に远加するず、Goのアセンブラヌがどれだけ奜きかを理解できたす。

ごく最近、私たちはHabréで、私たちが蚪れた䌚議に぀いお話したした。 それらの1぀はGopherCon 2016で、ほずんどすべおの人がGo-shnyアセンブラヌに関するRob "Commander" Pikeの話を芚えおいたす 。 蚘事ずしおデザむンされた圌のレポヌトの翻蚳をお芋せしたす。 私は、りィキペディアの関連蚘事ぞの可胜な限り倚くのリンクをテキストで提䟛しようずしたした。

アセンブラヌ これはマンモスのような叀代のものです



Rob PikeがGopherCon 2016で出挔

よろしくお願いしたす これは、長幎にわたるアセンブリ蚀語に関する報告曞に察する最も熱心な回答です。 あなたは尋ねるかもしれたせんなぜアセンブラヌに぀いお話す必芁があるのですか 理由はありたすが、それに぀いおは埌で。 たた、アセンブリ蚀語がどのような興味を持っおいるかも尋ねるこずができたす。 1970幎に戻っお、IBMマニュアルを芋おみたしょう。「最も重芁なこずは、アセンブラヌ蚀語の次の機胜を理解するこずです。プログラマヌは、System / 360マシンコヌドレベルでプログラミングしおいるようにSystem / 360コンピュヌタヌのすべおの機胜を䜿甚できたす」

倚くの点で、これらの蚀葉は時代遅れですが、基本的な考え方は䟝然ずしお真実です。アセンブラヌは、最も基本的なレベルでコンピュヌタヌず察話する方法です。 実際、今日でもアセンブリ蚀語が必芁です。 アセンブラヌだけがプログラマヌに任せられおいた時代がありたした。

その埌、いわゆる高レベル蚀語、たずえばFortranやKobolが登堎したした。これらはゆっくりず、しかし確実にアセンブラに取っお代わりたした。 しばらくの間、 C蚀語でさえアセンブラヌず比范しお高レベルず芋なされおいたした。 しかし、アセンブラヌの必芁性は今日も残っおいたす。アセンブラヌが提䟛するコンピュヌタヌぞのアクセスレベルのためです。

アセンブラヌは、環境の初期ロヌド、 スタックの動䜜、 コンテキストの切り替えに必芁です。 ちなみに、Goでは、ゎルヌチン間の切り替えもアセンブラで実装されおいたす。 たた、パフォヌマンスの問題もありたす。コンパむラの結果よりも効率的に動䜜するコヌドを手動で䜜成できる堎合がありたす。 たずえば、Go暙準ラむブラリの数孊/倧きなパッケヌゞの倧郚分はアセンブラで蚘述されおいたす。コンパむラをバむパスしお、それよりも優れたものを実装するず、このラむブラリの基本的な手順がはるかに効率的になるためです。 アセンブラヌは、新しい珍しいデバむス機胜や、高氎準蚀語では䜿甚できない機胜最新のプロセッサヌの新しい暗号化呜什などを操䜜するために必芁になる堎合がありたす。

しかし、私にずっお、アセンブリ蚀語で最も重芁なこずは、倚くの人がコンピュヌタヌに぀いおそれに぀いお考えるこずです。 アセンブリ蚀語は、コンピュヌタヌ操䜜の原則である䞀連の呜什のアむデアを提䟛したす。 アセンブラヌでプログラムを䜜成しない堎合でもここには䜕もないこずを願っおいたす、コンピュヌタヌの動䜜を理解するためだけにアセンブラヌに粟通しおいる必芁がありたす。 ただし、アセンブリ蚀語自䜓にあたり泚意を払うこずはありたせん。これは私のレポヌトの考え方ず䞀臎しおいたす。

倚くの異なるアセンブラヌ


あなたの倚くは、アセンブリ蚀語にあたり詳しくありたせん。 したがっお、幎代順を順守しようずしお、いく぀かの䟋を挙げたす。

IBMシステム/ 360

1        PRINT NOGEN 2 STOCK1 START 0 3 BEGIN  BALR  11,0 4        USING *,11 5        MVC   NEWOH,OLDOH 6        AP    NEWOH,RECPT 7        AP    NEWOH,ISSUE 8        EOJ 11 OLDOH DC    PL4'9' 12 RECPT DC    PL4'4' 13 ISSUE DC    PL4'6' 14 NEWOH DS    PL4 15       END   BEGIN 

これはIBM System / 360アセンブラヌです。 匕甚が最初にあったのはこのコンピュヌタヌに぀いおでした。 意味に泚意を払うのではなく、芋おください。

そしお、これは党䜓像を瀺すこずです。

Apollo 11ガむダンスコンピュヌタヌ

 # TO ENTER A JOB REQUEST REQUIRING NO VAC AREA:         COUNT     02/EXEC              NOVAC     INHINT         AD        FAKEPRET     # LOC(MPAC +6) - LOC(QPRET)         TS        NEWPRIO      # PRIORITY OF NEW JOB + NOVAC C(FIXLOC)         EXTEND         INDEX     Q            # Q WILL BE UNDISTURBED THROUGHOUT.         DCA       0            # 2CADR OF JOB ENTERED.         DXCH      NEWLOC         CAF       EXECBANK         XCH       FBANK         TS        EXECTEM1         TCF       NOVAC2       # ENTER EXECUTIVE BANK. 

これは、Apollo 11オンボヌド制埡コンピュヌタヌ甚のアセンブラヌコヌドです。 圌のプログラムはすべお完党にアセンブラヌで曞かれおいたす。 アセンブラヌは私たちが月に行くのを助けおくれたした。

PDP-10

 TITLE   COUNT A=1                             ;Define a name for an accumulator. START:  MOVSI A,-100            ;initialize loop counter.                               ;A contains -100,,0 LOOP:   HRRZM A,TABLE(A)        ;Use right half of A to index.       AOBJN A,LOOP            ;Add 1 to both halves (-77,,1 -76,,2 etc.)                               ;Jump if still negative.       .VALUE                  ;Halt program. TABLE:  BLOCK 100               ;Assemble space to fill up. END START                       ;End the assembly. 

これはPDP-10のアセンブラヌであり、他の䟋ず比范するず非垞にコメントされおいたす。

PDP-11

 / a3 -- pdp-11 assembler pass 1 assem:       jsr     pc,readop       jsr     pc,checkeos       br      ealoop       tst     ifflg       beq     3f       cmp     r4,$200       blos    assem       cmpb    (r4),$21   /if       bne     2f       inc     ifflg 2:       cmpb    (r4),$22   /endif       bne     assem       dec     ifflg       br      assem 

これはPDP-11のスニペットです。 さらに、これはUnix v6のアセンブラヌ甚のコヌドです-もちろん、アセンブラヌで曞かれおいたす。 C蚀語は埌で䜿甚され始めたした。

モトロヌラ68000

 strtolower      public               link    a6,#0           ;Set up stack frame               movea   8(a6),a0        ;A0 = src, from stack               movea   12(a6),a1       ;A1 = dst, from stack loop            move.b  (a0)+,d0        ;Load D0 from (src)               cmpi    #'A',d0         ;If D0 < 'A',               blo     copy            ;skip               cmpi    #'Z',d0         ;If D0 > 'Z',               bhi     copy            ;skip               addi    #'a'-'A',d0     ;D0 = lowercase(D0) copy            move.b  d0,(a1)+        ;Store D0 to (dst)               bne     loop            ;Repeat while D0 <> NUL               unlk    a6              ;Restore stack frame               rts                     ;Return               end 

Cray-1

 ident slice        V6        0               ; initialize S        A4        S0              ; initialize *x        A5        S1              ; initialize *y        A3        S2              ; initialize i loop     S0        A3        JSZ       exit            ; if S0 == 0 goto exit        VL        A3              ; set vector length        V11       ,A4,1           ; load slice of x[i], stride 1        V12       ,A5,1           ; load slice of y[i], stride 1        V13       V11 *F V12      ; slice of x[i] * y[i]        V6        V6 +F V13       ; partial sum        A14       VL              ; get vector length of this iteration        A4        A4 + A14        ; *x = *x + VL        A5        A5 + A14        ; *y = *y + VL        A3        A3 - A14        ; i = i - VL        J        loop exit 

これは、Motorola 68000甚のアセンブラヌであり、Cray-1甚です。 私はこの䟋が奜きです;それはロバヌト・グリヌれマヌの論文からです。 それがすべお始たった方法を思い出しおください。


RobertGriseméerがGopherCon 2015に出挔

これらはすべお異なる蚀語であるこずに気付くかもしれたせんが、いく぀かの点で䌌おいたす。共通の非垞に明確な構造を持っおいたす。

説明曞

 subroutine header label:   instruction operand...    ; comment   ... 

オペランド

 register literal constant address register indirection (register as address) ... 

通垞、アセンブラヌ・プログラムは列に曞き蟌たれたす。巊偎にはラベルがあり、次に呜什、オペランド、そしお最埌に右偎にコメントがありたす。 オペランドは通垞、レゞスタ、定数、たたはメモリアドレスですが、異なるアヌキテクチャに察しお構文的には非垞に䌌おいたす。 䟋倖がありたす。 Crayの䟋は背景に察しお際立っおいたす。加算コマンドは、算術匏のように+蚘号ずしお蚘述されおいたす。 しかし、意味はどこでも同じです。これは远加コマンドであり、これらはレゞスタです。 ぀たり、これはすべお実際には同じこずです。

蚀いかえれば、昔でも、私の時代でさえ、プロセッサヌは珟圚ずほが同じでした。 反䟋もありたすが、詳现に泚意を払わなければ、実際にはほずんどのプロセッサおよびGoが実行されるすべおのプロセッサは同じたたです。 詳现に觊れない堎合、興味深い結論に達するこずができたす。これらすべおのコンピュヌタヌに぀いお、共通の文法を䜜成できたす。 この事実を理解するのに玄30幎かかりたした。

ケンの玠晎らしいアむデア



巊からロバヌト・グリスメむダヌ、ロブ・パむク、ケン・トンプ゜ン

1980幎代半ば頃、ケントンプ゜ンず私は開発に぀いお考え始め、それがプラン9に倉わりたした。 Kenは新しいCコンパむラを䜜成したした。これはGoツヌルのCコンパむラの基瀎を圢成し、最近たで䜿甚されおいたした。 National 32000プロセッサを䜿甚したSequent察称マルチプロセッサコンピュヌタ䞊にありたした。 私の意芋では、これは集積回路ずしお垂販されおいる最初の32ビットマむクロプロセッサでした。 しかし、ケンは1぀の興味深いこずをしたした-ある人はそれを理解したせんでしたが、それは非垞に重芁であるこずが刀明したした。 これは䞀般的にケンの特城的な機胜です。

コンパむラは機械語呜什を生成したせんでした-擬䌌コヌドのようなものを生成したした。 次に、2番目のプログラム実際にはリンカヌ がコンパむラヌの結果を取埗し、これらの疑䌌呜什を実際の呜什に倉換したした。

呜什のような

 MOVW    $0, var 

ちょうどなる可胜性がありたす

 XORW    R1, R1 STORE   R1, var 

抜象的な䟋を挙げたす。 たずえば、倉数にれロを蚭定するMOVW呜什がありたす。 コンピュヌタで実行されるリンカによっお発行されるコヌドは、たずえば、䞡方のオペランドずしお同じレゞスタが指定されおいる぀たり、レゞスタ倀をリセットするXORW呜什ず、このレゞスタの倀を倉数に入れるSTOREで構成されたす。 詳现に぀いおは心配しないでください。ここでのポむントは、コンピュヌタヌが実行する呜什がアセンブラヌで入力したものず正確に䞀臎しない堎合があるずいうこずです。

疑䌌呜什に基づいお実際の呜什をコンパむルするこのプロセスは、呜什遞択ず呌ばれるものです。 疑䌌呜什のすばらしい䟋は、ケンがRETを呌び出した関数からのreturnステヌトメントです。 30幎前から呌ばれおいたすが、その実装は実行するコンピュヌタヌによっお異なりたす。 䞀郚のコンピュヌタヌのマニュアルではRETず呌ばれおいたすが、別のコンピュヌタヌでは、レゞスタヌに含たれるアドレスぞの移行、特殊レゞスタヌのアドレスぞのリダむレクト、たたはたったく別のこずができたす。

したがっお、アセンブラは、コンパむラが生成する疑䌌呜什を蚘述する方法ず芋なすこずができたす。 プラン9の䞖界では、他のほずんどのアヌキテクチャずは異なり、コンパむラヌはアセンブラヌを実行したせん。デヌタはリンカヌに盎接転送されたす。



その結果、プロセスは次のようになりたす。 䞀番䞊の行は、埓来のアヌキテクチャにほが察応しおいたす。 私の意芋では、GCCは今日ず同じように機胜したす。 これはコンパむラであり、高レベルのコヌドを受け取り、アセンブリ蚀語コヌドに倉換したす。 アセンブラヌは実際の呜什を生成し、リンカヌは個々のパヌツをリンクしおバむナリを䜜成したす。 䞋の2行は、プラン9の状況を瀺しおいたす。実際、アセンブラヌは半分に分割されおいたす。半分はコンパむラヌに残り、2番目はリンカヌの䞀郚になりたした。 赀い線を暪切る矢印は、バむナリ衚珟の疑䌌呜什のストリヌムです。 Plan 9のアセンブラヌの目的の1぀は、リンカヌが凊理する疑䌌呜什に倉換するテキスト圢匏の呜什を䜜成する機胜を提䟛するこずです。

アセンブラヌゎヌ


この状況は、倚くの䞖代にわたっお続いおいたす。 たた、Plan 9アセンブラヌもそれに察応しおいたした。これらは、アヌキテクチャごずに独自のYacc文法を持぀個別のCプログラムでした。 それらは独特のセットたたはパッケヌゞを圢成したしたが、これらは別個の独立しお曞かれたプログラムでした。 圌らは共通のコヌドを持っおいたしたが、完党ではありたせん...䞀般的に、すべおが耇雑でした。 その埌、Goが衚瀺され始めたした... 2007幎に... Goコンパむラ-8gず6gがこの面癜い名前のプログラム矀に远加されたした。 そしお、圌らは同じモデルを䜿甚したした。 これらは図の䞭倮の線に察応しおいたす。 たた、この分離の実装方法は、内郚Goデバむスに倚くの利点をもたらしたしたが、今日は詳しく説明する時間がありたせん。


ラスコックスがGopherCon 2015でパフォヌマンス

Go 1.3では、すべおのCコヌドを取り陀き、すべおをGoのみに実装したかったのです。 しばらく時間がかかりたす。 しかし、Go 1.3のリリヌスでは、このプロセスを開始したした。 すべおは、Russ Russ Cox がリンカヌの倧郚分を取り、それを分離したずいう事実から始たりたした。 これがliblinkラむブラリの出珟方法であり、そのほずんどはいわゆる呜什遞択アルゎリズムによっお占有されおいたした。 珟圚、このラむブラリはobjず呌ばれおいたすが、その埌はliblinkず呌ばれおいたした。 コンパむラヌは、このliblinkラむブラリヌを䜿甚しお、疑䌌呜什を実際の呜什に倉換したした。 この決定を支持するいく぀かの議論がありたした。

これらの䞭で最も重芁なのは、組み立おプロセスの高速化です。 コンパむラは珟圚より倚くの䜜業を行っおいたすが、今では呜什を遞択しおいたすが、リンカはこれを実行しおいたした。 このようなデバむスのおかげで、圌はこれを各ラむブラリに察しお1回だけ実行しおいたす。 以前は、たずえばfmtパッケヌゞをビルドする必芁がある堎合、 毎回Printfの指瀺の遞択が再床実行されおいたした。 明らかに、これは愚かです。 ここで䞀床実行するず、リンカヌはこれを実行する必芁がなくなりたす。 その結果、コンパむラヌは遅くなりたすが、アセンブリヌ党䜓は速くなりたす。 アセンブラも同じ方法で構築でき、objラむブラリを䜿甚できたす。

このステヌゞの最も重芁な機胜は、ナヌザヌにずっお䜕も倉わっおいないこずです。入力蚀語は同じたたで、出力は同じたたで、それでも同じバむナリファむルであり、詳现のみが異なりたす。 叀いアヌキテクチャの䞀般的な抂芁を次に瀺したす。コンパむラ、アセンブラ、リンカ。 プラン9の䞖界では、リンカヌはコンパむラヌたたはアセンブラヌによっお制埡されたす。

叀いアヌキテクチャ



新しいアヌキテクチャ



バヌゞョン1.3では、このようなデバむスに切り替えたした。 ご芧のずおり、今でははるかに䌝統的なリンカがありたす呜什の遞択を実行するobjラむブラリはリンカの䞀郚ではなくなり、コンパむラずアセンブラの最終段階になったため、実際の呜什を受け取りたす。 ぀たり、プロセスにアセンブラヌを含めるず、アセンブラヌずコンパむラヌは叀いスキヌムずの敎合性が向䞊したす。

この新しいGoアセンブラは奇劙なものです。 単玔に䜕もありたせん。 圌は䜕をしおいたすか 疑䌌呜什のテキスト蚘述をリンカの実際の呜什に倉換したす。 1.5では、倧きな䞀歩を螏み出したした-Cを取り陀きたした。このため、1.3および1.4で倚くの準備䜜業を行い、この問題はようやく解決されたした。 Russは、Cで䜜成されたGoコンパむラヌおよび、ちなみにリンカヌの叀い゜ヌスコヌドをGoプログラムに倉換するトランスレヌタヌを䜜成したした。

叀いliblinkラむブラリはラむブラリセットに組み蟌たれおおり、ここではたずめおobjず呌びたす。 その結果、objず呌ばれるものがありたす。これは移怍可胜な郚分であり、各アヌキテクチャの機胜に関する情報を保存するマシン䟝存の郚分を持぀サブディレクトリです。 いく぀かのレポヌトがこの䜜業に圓おられおいたす。これ自䜓は興味深い話です。 2幎前、ラスはGopherConでプレれンテヌションを行いたしたが、圌はすでにかなり時代遅れです。 実際、私たちは圌が圓時蚀ったこずを正確にはしたせんでした。 そしお、GopherFest 2015で、バヌゞョン1.5の倉曎のより䞀般的でより正確な抂芁を玹介したした。

 GOOS=darwin GOARCH=arm go tool compile prog.go 

だからここに。 コンパむラは、6g、8g、およびその他の奇劙な名前ず呌ばれおいたした。 これは、コンパむルず呌ばれる1぀のプログラムです。 コンパむルツヌルを実行し、暙準のGOOS環境倉数「goose」を「goose」ず発音およびGOARCH「gorch」を「酔っぱらった、バヌの貪欲な男」ず発音の倀を蚭定しお調敎したす。これが名前の正匏な発音です。 リンカに぀いおも同じこずをしたした。 リンクツヌルがあり、GOOSずGOARCHの倀を蚭定したす-プログラムをコンパむルできたす。 「1぀のコンパむラでこれらすべおのアヌキテクチャをどのようにサポヌトできたすか」 クロスプラットフォヌムのコンパむルが非垞に難しいこずは誰もが知っおいたす。」 実際、いいえ。 事前にすべおを準備する必芁がありたす。 これに泚意しおください。入力蚀語はGoだけです。 コンパむラの芳点から芋るず、結果も同じです。バむナリ圢匏の疑䌌呜什がobjラむブラリに転送されたす。 ぀たり、ツヌルの起動時に倉数の倀を蚭定するだけで、objラむブラリを構成する必芁がありたす。 あなたはすぐにそれを行う方法を孊びたす。

アセンブラに぀いおは、CからGoぞのアセンブラの機械翻蚳を実行したしたが、これは理想的な゜リュヌションではなく、私はそれが奜きではありたせんでした。 私はGoをれロから曞くこずを、それらすべおを眮き換える唯䞀のプログラム、asmを提案したした。 セットアップは、GOOSずGOARCHを介しおのみ行われたす。 アセンブリ蚀語ずGoは同じものではないこずに気付くかもしれたせん。 各プロセッサには、独自の呜什セット、独自のレゞスタセットがあり、これは単䞀の出力蚀語ではありたせん。 それをどうしたすか しかし、実際には、それらは本質的に同じです。 ご芧ください。

 package add func add(a, b int) int {   return a + b } 

以䞋は、2぀の敎数を加算しお合蚈を返す簡単なプログラムの䟋です。 -Sフラグを䜿甚しおアセンブラコヌドを衚瀺した堎合にコンパむラが提䟛する擬䌌呜什は衚瀺したせん。 たた、倚くの䜙分なものを削陀したした-この方法を䜿甚するず、倚くの䞍芁なものも衚瀺されたすが、この段階でコンパむラヌはたさにそのような疑䌌呜什を生成したす。

32ビットx86386

 TEXT add(SB), $0-12   MOVL    a+4(FP), BX   ADDL    b+8(FP), BX   MOVL    BX, 12(FP)   RET 

64ビットx86amd64

 TEXT add(SB), $0-24   MOVQ    b+16(FP), AX   MOVQ    a+8(FP), CX   ADDQ    CX, AX   MOVQ    AX, 24(FP)   RET 

32ビットアヌム

 TEXT add(SB), $-4-12   MOVW    a(FP), R0   MOVW    b+4(FP), R1   ADD     R1, R0   MOVW    R0, 8(FP)   RET 

64ビットアヌムarm64

 TEXT add(SB), $-8-24   MOVD    a(FP), R0   MOVD    b+8(FP), R1   ADD     R1, R0   MOVD    R0, 16(FP)   RET 

S390s390x

 TEXT add(SB), $0-24   MOVD    a(FP), R1   MOVD    b+8(FP), R2   ADD     R2, R1, R1   MOVD    R1, 16(FP)   RET 

32ビットアヌキテクチャのオプションを次に瀺したす。 詳现に぀いおは考えないでください。 党䜓像を芋おください。 64ビットx86アヌキテクチャの結果は、 AMD64ずも呌ばれ、32ビットARMアヌキテクチャ 、64ビットARMアヌキテクチャ、およびIBM System / 390アヌキテクチャの結果です。 私たちにずっおは新しいものですが、他のすべおにずっおは明らかにそうではありたせん。

64ビットMIPSmips64

 TEXT add(SB), $-8-24   MOVV    a(FP), R1   MOVV    b+8(FP), R2   ADDVU   R2, R1   MOVV    R1, 16(FP)   RET 

64ビットの電源ppc64le

 TEXT add(SB), $0-24   MOVD    a(FP), R2   MOVD    b+8(FP), R3   ADD     R3, R2   MOVD    R2, 16(FP)   RET 

64ビットMIPSアヌキテクチャのコヌドは次のずおりです。64ビットPOWERアヌキテクチャは次のずおりです。 䌌おいるこずに気付くかもしれたせん。 その理由は、実際には、それらがたったく同じ蚀語であるためです。 その理由の1぀は、そのように配眮されおいるこずです。実際、National 32000アセンブラヌを30幎間䜿甚し、䜿甚されたハヌドりェアのみを倉曎したした。 しかし、それらのいく぀かは本圓に同䞀だからです。 これらは、呜什、レゞスタ、オペランド、定数倀、ラベルにすぎたせん-すべお同じです。 唯䞀の重芁な違いは、呜什ずレゞスタの名前が異なるこずです。 オフセットも異なる堎合がありたすが、機械語のサむズによっお異なりたす。

それはすべお、Kenが曞いたNational 32000アセンブラヌに芁玄されおいたす。 これは、Kenが想像するように、最新のPowerPCに適合したNational 32000アセンブリ蚀語です。 したがっお、必芁なものすべお-共通の入力蚀語、バック゚ンドのobjラむブラリ-があり、アセンブラヌで蚘述できたす。 このアプロヌチでは、問題が発生したす。NationalたたはPowerPCのリヌダヌシップを取り、アセンブラヌ蚀語を芋るず、そのようには芋えないこずがわかりたす。 あるレベルでは実際には疑䌌呜什であるため、構文は異なり、呜什名も異なる堎合がありたす。 実際、問題ではありたせん。

初心者には、Goアセンブラヌの倖芳これらすべおの倧文字ず奇劙なものが深刻に混乱する可胜性がありたす。 しかし、これらすべおのコンピュヌタヌに共通のアセンブリ蚀語があるため、以䞋で説明するすばらしい結果を埗るこずができたす。 したがっお、これは正圓な劥協案であり、それを達成するこずはそれほど難しくないず考えおいたす。 68000およびアセンブラヌKenでプログラミングするこずを孊ぶ䟡倀がありたす。たた、PowerPC甚のプログラムを自動的に䜜成できたす。 違いは䜕ですか

どのように機胜したすか アセンブラヌバヌゞョン1.5では、アセンブラヌが理想的だず考えおいたす。 圌にコンピュヌタヌを枡しおください-そしお圌は圌のためにアセンブラヌを翻蚳したす。 これは完党にGoで曞かれた新しいプログラムです。 䞀般的なレキシカルアナラむザヌず構文アナラむザヌがあり、入力コヌド、ナヌザヌが提䟛するすべおのものを取埗し、呜什をバむナリ圢匏の呜什を蚘述するデヌタ構造に倉換しおから、特定のプラットフォヌムに関する情報を含む新しいobjラむブラリに結果を転送したす。

アセンブラの基瀎ずなるコヌドのほずんどは完党に移怍可胜であり、アヌキテクチャに関する興味深い情報は䜕も含たれおいたせんが、レゞスタ名に関する情報を含むテヌブルがありたす。 オペランドの操䜜に関連するものがただいく぀かありたすが、非垞に簡単です。 そしお、これらはすべお、GOARCH倉数の倀に埓っおプログラムが開始されるずきに構成されたす。 GOOSは、掘り䞋げない非垞にたれなケヌスで䜿甚されたす。䞻な特性はGOARCHによっお決定されたす。 archず呌ばれるアセンブラ甚の内郚パッケヌゞもありたす。これらのテヌブルはオンザフラむで䜜成され、objラむブラリから動的に抜出されたす。 そしお、これが実際のコヌドのスニペットです。

 import (   "cmd/internal/obj"   "cmd/internal/obj/x86" ) func archX86(linkArch *obj.LinkArch) *Arch {   register := make(map[string]int16)   // Create maps for easy lookup of instruction names etc.   for i, s := range x86.Register {       register[s] = int16(i + x86.REG_AL)   }   instructions := make(map[string]obj.As)   for i, s := range obj.Anames {       instructions[s] = x86.As(i)   }   return &Arch{       Instructions:   instructions,       Register:       register,       ...   } } 

少し簡略化されおいたすが、本質を䌝えおいたす。 これは、内郚アセンブラパッケヌゞであるarchです。 これは、x86アヌキテクチャ甚にアセンブラ党䜓を構成する手順です。 このコヌドは、32ビットず64ビットの䞡方のアヌキテクチャで䜿甚されたすが、この芳点からは同䞀です。 そしお、ルヌプを開始したす... objプロシヌゞャ甚にx86パッケヌゞで定矩されたobjラむブラリからレゞスタ名を反埩凊理するルヌプ。 そしお、objからのデヌタに埓っおレゞスタ名ずバむナリに䞀臎するマップを蚭定するだけです。 そしお、指瀺に぀いおも同じこずを行いたす。

これらのコヌドは実際には呜什コヌドではなく、マニュアルには蚘茉されおいたせん。 これはすべおのものの文字通りアルファベット順のリストです-これらは単なる呜什であり、実際のコマンドではないこずを繰り返したす。 しかし、今ではすべおのレゞスタの名前ずすべおの呜什がわかっおいたす。 そしお、返すアヌキテクチャの説明には、これらの2぀のマップのみが含たれたす。 ここにあなたが知っおいる呜什の名前、ここにあなたが知っおいるレゞスタの名前、そしお私が蚀及しおいないいく぀かの事柄がありたすが、すべおはそこでずおも簡単です。 これは、アセンブリ蚀語をこれらのコンピュヌタヌの指瀺に倉換するために必芁なすべおの情報です。実際、パヌサヌは単に文字列のマッチングを行っお正しい呜什を芋぀けたす。列1にあり、単語が含たれおいたす。これは呜什です。呜什テヌブルで探しおいたす。ずおも簡単です。

 ADDW AX, BX &obj.Prog{   As: arch.Instructions["ADDW"],   From: obj.Addr{Reg: arch.Register["AX"]},   To: obj.Addr{Reg: arch.Register["BX"]},   ... } 

以䞋に䟋を瀺したす。 « » (ADDW) 386, . : ADDW AX, BX. , . , , — , , ADDW . A — , . , . — AX, BX. , , : , , obj. , . , , — . .

, , . . , , , 
 , , , . これは問題ではありたせん。
, obj. : , , obj, , , obj , . , obj , . .

, , , , . . , , , 
 obj , , . , , , . . , , . それは、䞀般に、すべおです。 A/B- — . .

386, – AMD64. , . , PowerPC, – . , , , . , obj, .

-, . , Go, Yacc. , . . Go, , . , , , . , . , . . . . .

, , , , , open-source-. Git , , , , , . これは玠晎らしい。 -, . , open-source- .

, , , , obj . ? . , , 
 — , pprof, — -, , , , , . , PDF , . , , — ? . , . . , .

— , . . . . , , . , PDF , – . .
, , , , .

おわりに


. , , . , . , , . , , . , . — , . — , — . , , , .

Go. ありがずう

Source: https://habr.com/ru/post/J317864/


All Articles