質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • アセンブリ言語

    105questions

    アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

  • アーキテクチャ

    81questions

    アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

  • CPU

    33questions

  • リンカ

    6questions

    リンカはコンパイルされたオブジェクトコードに、必要なライブラリなどを付け加えて、実行可能ファイルを生成するプログラムです。コンパイルされたオブジェクトのコードを複数のファイルで取得し、"linked"という一つの実行可能のファイルを生成します。

  • 機械語

    6questions

    機械語とは、プロセッサが直接解釈・実行できる状態の言語です。

リンカの働き、アセンブリプログラムをアセンブルにより機械語に変換する。

受付中

回答 7

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 618

carnage0216

score 120

リンカとはosに依存するツールだと書いてあったのですが、いまいちリンカが何なのかわかりません。
リンカがソフトとも書いてありましたが、C言語をコンパイルしてアセンブリプログラムをアセンブルする過程でリンカが働いているのでしょうか?
リンカと調べるとリンカスクリプトと出てきてリンカについての情報が曖昧です。
どうかリンカが何なのか教えて頂けないでしょうか?
アセンブリ言語とは直接でないにしても関係のあるような記事はいくつかありました。
アセンブリプログラムのアセンブル(アセンブリ用のコンパイラ)がリンカなのでしょうか?

編集
図書館で調べたり、書店で立ち読みしたり、サイトで調べた結果。
Linuxで複数のアセンブリプログラムを一つにするのかに、リンカが必要だそうですが、リンカを使わないで、複数のアセンブリプログラムを一つにまとめて見ます。これに関してはリンカ自体を手作業でやるようなものであり、何ヶ月、何年かかるかわかりませんが。好奇心が満たせるなら行いたいです。
また、一つにしたアセンブリプログラムをメモリに入れる際のメモリの指定も自分でやってみます。
リンカの行なっていることを手作業でやることで、知識が深まると思います。
また、アセンブリプログラムを機械語に変換するのに、リンカが関係ないこともわかりました。
なぜなら、複数のアセンブリプログラムを一つにするのがリンカ
の役割で、その一つにしたアセンブリプログラムをメモリに収納するまでが、リンカの仕事で、あとはアセンブルが単純にアセンブリ命令に対応した機械語を出力するだけですので。
確認として以上の認識であっていますか?間違っていたら怖いのでお願いいたします。
まぁ、以上の話からアセンブリプログラムを機械語に変化するアセンブラにはリンカが必要ないと書いてありました。また、リンカはあくまて複数のアセンブリプログラムを一つにするためにアセンブリプログラムのアドレスを基に複数のアセンブリプログラムを一つにするとも書いてありました。念のため確認します。

編集2
度々、すいません、

オブジェクトファイルにcpuに繋がる外部装置や、複数のアセンブリプログラムを一つにする為のアドレスやメモリ状況がわかるでしょうか?ならば、
オブジェクトファイルをアセンブリやニーモニックに変換するソフトを使えば、複数のアセンブリプログラムを一つにする方法や情報が書いてあるのでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 7

+2

リンカというのは実行ファイル(あるいはライブラリ)を作る、最後の段階の作業を行うものです。

  1. コンパイラにより高級言語のソースコードからオブジェクトファイルを作る
    (場合によってはいったんアセンブリ言語にするものもある)
  2. アセンブリ言語の場合はアセンブラがオブジェクトファイルを作る
  3. オブジェクトファイルをまとめ、ライブラリの依存関係を解消した状態で、最終結果の実行ファイルを作る(ライブラリによっては実行時に動的リンクをする設定になる場合もある)

リンカは最終的な実行ファイルを作成しているので、その時点で OS に依存します。オブジェクトファイルの段階では、CPU アーキテクチャには依存しますが、OS にはまだ依存しきっていません。とはいっても必要とするライブラリが OS 依存しますから、まず依存を解消することはできないのですけれども。

リンカがやることを手作業でやることに全く意味はありません。独自のコンパイラを作る場合でさえ、リンカまでは自作することはないのです。それこそ GCC のメンテナでも無い限り、リンカの挙動について考える必要なんて無いでしょう。

もっとも、最近の高級言語だと、Java や .NET のように、コンパイラはバイトコードと呼ばれる仮想マシンコードを作成し、実行は実行環境にある仮想マシンエミュレータがバイトコードを読み取りつつ動作するものもあります(こういう方法自体はそれこそ 8bit パソコンの時代にもありました)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/15 23:52 編集

    回答どうもありがとうございます。tacsheavenさんは無駄だといいますが、私にとっては好奇心を満たすという意味では大いに意味があるのです。
    リンカがやることを手作業でやることに意味がないのはわかりました。しかし、やり方があるのですよね。
    例えば、2つのアセンブリプログラムがあるとして、一つ目のプログラムが実行した後、二つめのプログラムが実行されるように、二つ目のプログラムの入っているメモリのアドレスを手作業で指定すれば、二つ目のプログラムが最初から実行されます。以上のようにリンカの作業を手作業でやるようなものは僕にとっては無駄ではないのです。勉強の一環として無駄ではないのです。
    以上の行為に大変興味があります。

    キャンセル

  • 2018/03/17 01:11

    リンカコマンド(ld)のソース読んで、手作業で同じことやればいいと思いますよ。
    https://github.com/gittup/binutils/tree/gittup/ld

    キャンセル

  • 2018/03/20 08:08

    素人の私にはその方法が良いかもしれませんどうもありがとうございます。

    キャンセル

+2

リンカというのは、複数のオブジェクトファイルをまとめて1つの実行形式のファイルを作る作業ですね。

コンパイル → アセンブル → リンク → 実行可能!

という流れですね。

具体的に、リンカは何をやっているかというと・・・
・セクションのマージ
・再配置
・シンボル解決

という3つが基本ですね。

例えば、readelf -S [オブジェクトファイル]で調べるとセクションの一覧が取得できます。

[14] .text             PROGBITS         00000000004005b0  000005b0
       00000000000001d2  0000000000000000  AX       0     0     16
  [15] .fini             PROGBITS         0000000000400784  00000784
       0000000000000009  0000000000000000  AX       0     0     4
  [16] .rodata           PROGBITS         0000000000400790  00000790
       0000000000000015  0000000000000000   A       0     0     4
  [17] .eh_frame_hdr     PROGBITS         00000000004007a8  000007a8
       0000000000000044  0000000000000000   A       0     0     4

複数のオブジェクトファイルからこの各セクションを取得し、1つにまとめます。

この後に、シンボル解決を行います。
これは、変数名や関数名というシンボルにアドレスを割り当てます。

nmコマンドを使うとシンボルを表示できます。

リンカの一番の仕事は「ロードするメモリアドレスの決定」であると考えています。

複数のセクションはセグメントという領域に割り当てられます。
これもリンカの仕事です。
readelf --segments [バイナリファイル] とやると確認できます。

02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got 
   03     .bss 
   04     .text .fini .rodata .eh_frame_hdr .eh_frame 
   05     .init_array .fini_array .dynamic .got .got.plt .data 
   06     .dynamic 
   07     .note.ABI-tag .note.gnu.build-id 

ローダはこのセグメント情報を元にメモリにロードします。
セグメントを作れば、実行することができます。
逆にセクメンとを持たないオブジェクトファイルは実行できません。

OSはシステムコールが発行されるとload_elf_binary()を使ってELF形式のバイナリファイルをメモリにロードするわけです。
(ちなみにLinux Kernel もELFなので、コンパイルする際にはリンカが必要です。)

このロードするアドレスは「リンカスクリプト」というファイルに記述されています。

ld --verbose とやると見ることができます。

SECTIONS
{
  /* Read-only sections, merged into text segment: */
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
  .note.gnu.build-id : { *(.note.gnu.build-id) }
  .hash           : { *(.hash) }
  .gnu.hash       : { *(.gnu.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rela.dyn       :
    {
      *(.rela.init)


リンカはこのスクリプト情報を元に、マージするセクション、ロード先のアドレスを決定します。

他にもリンカには静的リンク、動的リンクがあり、動的にリンクは実行の際にダイナミックリンカというプログラムが起動し、printfなのどのシンボル解決を行います。

通常、gcc test.c -o test とコンパイルすると動的リンクになります。
静的にリンクしたい時は、-static オプションを付けると可能です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/24 15:56

    ええーーーと、「リンカのやっていることを手作業でやる」というのは結構大変です。
    リンカは「実行可能形式のファイル」を作ることが仕事なので、もしもこれを手作業でやるには・・・

    プログラムヘッダーの作成、セクションヘッダーの作成、ELFヘッダの作成を行います。
    copy & pasteでセクションをまとめ、これら3つのヘッダを作れば可能です。

    この各ヘッダは ELF64_*という構造体が使われています。
    各メンバ変数に対してパラメータを入れなくてはいけません。
    例えば、ロードするメモリアドレス、セグメントの属性など・・・
    バイナリファイルを直接編集してそれをやるのは結構レベルが高いです。

    自分は、リンカを自作するほうが勉強になると思います。

    キャンセル

  • 2018/03/24 16:11

    わざわざ詳しい解説 どうもありがとうございます。strike1217さんの過去の質問や解答、非常に参考になるため勉強させていただいています。(過去に資料提供などでもお世話になりました。)
    はい、あの後、自分なりにリンカに関して勉強しました。(している途中でもあります。)
    静的リンカを使う場合はリンカが働かないため、自分でリンカの役割を手作業でしなければならないとしりました。
    また、見にくいし非効率ではありますが、複数のアセンブリソースを一つにまとめてアセンブラすればリンカは必要ないと調べて出てきました。(実行していないので本当かどうかはわかりません。)
    何はともあれ、勉強中の身でしてstrike1217さんの解答すべてを理解することはまだ困難ではありますが、よませていただきます。
    どうもありがとうございました。

    キャンセル

  • 2018/03/24 16:19

    ん?
    「静的リンカを使う場合はリンカが働かないため、自分でリンカの役割を手作業でしなければならないとしりました。」

    これは・・・どういうことでしょうか?
    静的リンクの際にもリンカを動きます。

    静的リンクというのは、「共有ライブラリを実行ファイルに直接埋め込む」のでリンカは必要ですね。

    「複数のアセンブリソースを一つにまとめてアセンブラすればリンカは必要ないと調べて出てきました。」
    これは・・・・??
    「手動でまとめれば、リンカは必要ない。」という意味ですかね?

    まとめるだけではダメです。
    アドレスを決定しなくてはいけないので、リンカは必要ですよ。

    キャンセル

  • 2018/03/24 16:26

    例えば、C言語のファイル1つだけで実行ファイルを作ろうとしてもリンカは必要です。

    なぜ、必要かと言いますと、「プログラムはmain()から始まるものではない」からです。

    実は、プログラムというのは、_startという位置から実行されます。
    それは、別のオブジェクトファイルにあるのですが・・・

    なので、一見1つのオブジェクトファイルに見えても実は複数のオブジェクトファイルを暗黙の内にまとめています。

    仮に最初からこれらのファイルが全部1つになっていたとしてもリンカは必要です。

    「アセンブラ」はアドレスの決定を行わないからです。
    最終的なロードアドレスの決定はリンカが行います。

    キャンセル

  • 2018/03/24 16:30

    アセンブルが出力したファイルを見ると分かるのですが・・・
    「オブジェクトファイル」というものには「セグメント情報」はありません。
    なので、「アセンブル」するだけでは、OSはバイナリファイルをメモリ上にロードすることは不可能です。

    「え?どこにロードするの???」ってなるはずです。

    なのでリンカは必要です。

    キャンセル

  • 2018/03/24 17:10

    勉強になります。
    どうもありがとうございます。

    キャンセル

  • 2018/03/24 17:15

    プログラムを逆アセンブルしてアセンブリ言語でアドレスを指定すれば、リンカは必要
    ないのでしょうか?
    大変非効率ですが。
    あの、>>「アセンブラ」はアドレスの決定を行わないからです。に書いてあるアセンブラはアセンブリ言語のコンパイラであり、アセンブリ言語の事ではないですよね?

    キャンセル

  • 2018/03/24 17:59

    「あの、>>「アセンブラ」はアドレスの決定を行わないからです。に書いてあるアセンブラはアセンブリ言語のコンパイラであり、アセンブリ言語の事ではないですよね?」

    そうですね。
    アセンブリ言語を機械語に変換するプログラムのことです。

    「プログラムを逆アセンブルしてアセンブリ言語でアドレスを指定すれば、リンカは必要ないのでしょうか?」
    ん??これは・・・「逆アセンブル」というのがどこの段階での事を言っているのかわからないのですが・・・・

    つまり、「アセンブリ言語で記述されたファイルのロード先アドレスの決定をアセンブリ言語で可能か??」
    ということでしょうか??

    それは・・・できますよね。
    リンカも所詮はプログラムなので、リンカをアセンブリ言語で書いている人はいないと思うのですが・・・可能でしょうね。

    その結果、既存のリンカは確かに不要になりますが、アドレスを決定するプログラムをアセンブリ言語で書くって・・・それは自作リンカですよね?

    それとも、「外部のプログラムに頼らずに、アセンブリ言語で書かれたプログラム自身が自分のロード先を決定することは可能か?」
    という意味ですか?
    そのような疑似命令が存在するかはわからないのですが・・・
    無理ではないでしょうか??
    アセンブラに作用する疑似命令があるならできるでしょうね。

    自身のセグメント情報をプログラム自身で書き換えることは可能ですが・・・それは、既にプロセスに変身している段階なので、アドレスの決定は「外部のプログラム」がやるしかないかと・・・

    キャンセル

  • 2018/03/24 19:05

    >>それは自作リンカですよね?
    いいえ、アセンブリプログラムないで呼び出したいライブラリのアドレスを直接書くのです。
    必要するライブラリのアドレスは無責任ではありますが、調べる方法はあると思います。

    キャンセル

  • 2018/03/24 19:55

    「呼び出したいライブラリのアドレスを直接書くのです。」

    それは・・・つまり「printfのような関数のアドレスを取得したい」ということですね。
    それは可能ですよね。

    オブジェクトファイルに直接ライブラリを埋め組む場合とそうでない場合で変わりますが。

    事実、dl_runtime_resolveはprintf関数のアドレスを探し出し、シンボル解決を行うので、それをアセンブリ言語で自分で書きたい・・・ということでしたら、可能だと思いますよ。

    キャンセル

  • 2018/03/24 20:01

    そうですか。
    よかったです。
    どうもありがとうございました。

    キャンセル

+1

リンカが行うリンクは、コンパイルやアセンブルの後処理で、実行プログラムを作ることです。
とりあえず、https://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%B3%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF を読んで不明点を書いてください。

リンカスクリプトとは、リンカにリンクの仕方を指示する場合に、それが複雑な場合の指示の記述のことです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

”リンカ”でググったらトップにそのものの説明が出てきたのですが、本当に調べました?

リンカとは、リンケージエディタのことで、機械語のプログラムの断片を結合し、実行可能なプログラムにするプログラムのことである。 例えば、C言語の場合、ソースファイルをコンパイルするオブジェクトファイルが生成され、それに他のオブジェクトファイルやライブラリを結合し、1つのプログラムにする。

https://it-words.jp/w/E383AAE383B3E382AB.html

リンカスクリプトはリンカに食わせるスクリプトで、プログラマがプログラムやデータの配置アドレスを指定したい場合に使います。
用途としては主に組み込み分野で、リアルタイムOSやベアメタルのプログラムを作った時に、プログラムを配置するROMやメモリのアドレスを指定したりします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/14 00:57

    私の事なので信用がないのは残念ですが、調べました。
    リアルタイムOSやベアメタルのプログラムを作った時に、プログラムを配置するROMやメモリのアドレスを指定したりします。
    これはすごく興味深いです!

    キャンセル

  • 2018/03/14 02:26

    リンカスクリプトを理解しよう
    https://www.computex.co.jp/article/use_gcc_1.htm

    ちなみにWindowsやLinux上で動作するアプリケーションを作る分にはリンカスクリプトなんてまず使いませんので。

    キャンセル

+1

例えば、C言語から標準ライブラリのprintfで文字列を表示するプログラムがあったとします。このプログラムをコンパイルすると、その機械語は作成できますが、この中にprintfを実行するための機械語はありません。
リンカとは、標準ライブラリや別のソースプログラムから作成された機械語をくっつけて一つの実行できる機械語(実行形式)にするものです。実行形式は、それぞれのOSによってメモリに配置する方法がことなります。例えば、MacもWindowsも同じicoreチップで動作しますが、実行プログラムは動作しません。
ランカーの仕事は、先程の例では、mainプログラムの中のprintfを呼び出す機械語部分のアドレスを、標準ライブラリからくっつけたprintfモジュールがどのアドレスに配置されるのか算出したアドレス値に書き換えます。
今では、リンクの作業は、ダイナミックリンク(動的リンク)に取って代わり、プログラム実行時に自動的に行われるようになっています

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/14 19:47

    解答ありがとうございます。
    あの、扱うプログラムはアセンブリプログラムだとしてリンカの役割をリンカを使わずに手作業?で複数のアセンブリプログラムを一つにしたり、一つにしたアセンブリプログラムを保存するメモリを指定できないでしょうか?
    osはLinuxで行いたいと考えています。
    もし複数のアセンブリプログラムを一つできるとしたら、
    どのようにするのでしょうか?MSDOSなどを使うのですか?
    ちなみに、
    リンカを手作業でするのは、難しいというか面倒なのでしょうか?

    キャンセル

  • 2018/03/14 19:55

    ELFフォーマットについて理解すればできるんじゃないですかね。
    https://ja.wikipedia.org/wiki/Executable_and_Linkable_Format

    手作業でやる場合はバイナリエディタとか使うんだと思います。

    キャンセル

  • 2018/03/14 22:26

    リンクを手作業で行うのは現実的ではありません。分割してコンパイルした各オブジェクトをくっつけるだけでありません。外部シンボルのアドレスを解決する必要がありますが、これは、全モジュールをくっつけてみないとそのアドレスは、分かりません。
    さらに、各オブジェクトの中でこれらの外部シンボルを参照している機械語(CALL命令のアドレスや外部シンボルを参照しているMOVE命令)のアドレス部分を修正する必要もあります。
    しかも、アドレス書き直す最に、インテル系のチップの場合、CALL命令のアドレスは自己相対アドレスといって、CALL命令からどれだけ離れているかオフセットを書き込む必要があります。
    このようにリンクを手動で行うことは無理と言っていいでしょう。
    ただし、私の知っている内容は、昔の8086の頃の話なので、現在はどのようにして外部シンボルのアドレス解決しているのかは、わかりません。ひっとすると、セグメントレジスターを使ってもっと簡単で行っているかもしれません。

    キャンセル

  • 2018/03/15 23:22

    >リンクを手作業で行うのは現実的ではありません。
    まあ、そうですよね。

    キャンセル

  • 2018/03/16 00:19

    現実的ではないかもしれませんが、「分割してコンパイルした各オブジェクトをくっつけるだけでありません。外部シンボルのアドレスを解決する必要がありますが、これは、全モジュールをくっつけてみないとそのアドレスは、分かりません。
    さらに、各オブジェクトの中でこれらの外部シンボルを参照している機械語(CALL命令のアドレスや外部シンボルを参照しているMOVE命令)のアドレス部分を修正する必要もあります。
    しかも、アドレス書き直す最に、インテル系のチップの場合、CALL命令のアドレスは自己相対アドレスといって、CALL命令からどれだけ離れているかオフセットを書き込む必要があります。
    このようにリンクを手動で行うことは無理と言っていいでしょう。」より大変面白そうです。

    キャンセル

  • 2018/03/16 00:20

    簡単に行えるかもしれないとのことでセグメントレジスターで調べてみます。

    キャンセル

  • 2018/03/16 11:20

    度々、質問すいません。


    オブジェクトファイルにcpuに繋がる外部装置や、複数のアセンブリプログラムを一つにする為のアドレスやメモリ状況がわかるでしょうか?ならば、
    オブジェクトファイルをアセンブリやニーモニックに変換するソフトを使えば、複数のアセンブリプログラムを一つにする方法や情報が書いてあるのでしょうか?

    キャンセル

  • 2018/03/20 08:06

    残念ながら、最近のPCでOSがどこまで行ってあるのかわかりません。
    昔の8ビットOSでは、アセンブラが出力したオブジェクトをメモリに貼り付けて実行まで簡単に想像できましたが、最近のOSでは、仮想メモリ機構がありますので、一体どのようにしてメモリに貼り付ける事すら想像できません。

    キャンセル

  • 2018/03/20 08:09

    CPUが複雑化したせいでOSまでも複雑で膨大なデータになってしまったのですね。
    他の方法を探してみます。どうもありがとうございます。

    キャンセル

+1

なぜなら、複数のアセンブリプログラムを一つにするのがリンカ
の役割で、その一つにしたアセンブリプログラムをメモリに収納するまでが、リンカの仕事で、あとはアセンブルが単純にアセンブリ命令に対応した機械語を出力するだけですので。

間違った認識です。

  • アセンブラ(as)
    アセンブリソース(hello.s)から不完全な機械語を含む中間生成物(hello.o)を作成する。
  • リンカ(ld)
    中間生成物(hello.o)から実行ファイル(hello.exe)を作成する。
  • ローダー(ツールというかOSもしくはBIOS)
    実行ファイル(hello.exe)を実行するよう命令されたOSが(多くの場合、仮想の)メモリ上に
    実行ファイルやライブラリ(.dll)等を読み込み。実行ファイルに指定されたアドレスをエントリーポイントとして呼び出します。

アセンブリ言語は規格化された言語とは違いますので、アセンブラ毎に処理や生成物等が違う可能性がありますが
少なくともGNUアセンブラではこんな感じです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

複数の中間生成物(hello.o)から実行ファイル(hello.exe)を作成する。 
hello.o はユーザが作ったコードを意味している感じますが、リンカは、システムに存在するライブラリも連結します。printf("hello")ならprintfはどこかで定義されていて、ウインドウを作ってその中に色付きの文字を表示するならそのウィンドウを準備したり、#112233みたいな色をハードの教えるために部分が必要になります。
printfを間違えてprintgとしてもアセンブラは文句を言いませんが、リンカでprintgが見つからないというエラーになります。asmさんのコメントにあるように部分的にロード時まで解決を遅らせることもできます。
dllの場合は、すでに読み込まれているdllを利用できる場合、実行途中でリンクする場合などもっと複雑な方法が取れます。Linuxの場合、実行途中でシステムのライブラリをデバッグ・ハッキングのために自作のものに切り替えたり、それを阻止するような対策を打つことがあります。
 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    アセンブリ言語のレジスタに64bitのアドレスを入れる方法

    x86_64系のアセンブリ言語を勉強しています。 レジスタの中にmovでメモリアドレスを直接代入したい場合などはどうすればよろしいのでしょうか? mov rax,0x000

  • 解決済

    アセンブリ

    アセンブリ言語で質問があります。 C言語のプログラムをコンパイルした際に出てくるアセンブリ言語の一部なんですが、main()前の初期化の箇所で以下のような部分がありました。

  • 解決済

    解決済み

    以下の英語での動作をするようなプログラムを作れと言われてるんですが、ポインタとスタックの意味がよくわかりません。よければ教えてほしいです。

  • 解決済

    nasm システムコールの疑問

    自分はnasm 16bit のプログラミングを勉強したものです 今はnasm 32bitをubuntuの端末で動かそうとしているのですが nasm16bitではシステムコールがin

  • 解決済

    ただファイルを開くだけのプログラム

    Ubuntuの端末で動くアセンブリ言語のただファイルを開くだけのシステムを作ってみましたが実行コアダンプが発生します。 具体的には開くだけのシステム+開けたかどうか表示をするプログ

  • 解決済

    アセンブラ言語における「ラベル」とは何なんでしょうか?初心者でもわかりやすいように教えてください。

    1週間で学ぶIT基礎の基礎 - 【5分で覚えるIT基礎の基礎】だれでも一度はアセンブラを学んでおこう! 第2回:ITproのページに ラベルとは,アセンブラのプログラムの

  • 解決済

    アセンブリ言語を使うメリットについて。

    アセンブリ言語を使っている方にお聞きしたいのですが、使用しているCPUあるいはGPUの構造を細かい部分(メモリ、レジスタ、演算回路など)を把握したうえでアセンブリ言語を扱っているの

  • 解決済

    オブジェクトファイルの分析

    オブジェクトファイルをアセンブリ言語に変換するソフトを使う事で、cpuに繋がる外部装置や、複数のアセンブリプログラムを一つにする為のアドレスやメモリ状況がわかるでしょうか?ならば、

同じタグがついた質問を見る

  • アセンブリ言語

    105questions

    アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

  • アーキテクチャ

    81questions

    アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

  • CPU

    33questions

  • リンカ

    6questions

    リンカはコンパイルされたオブジェクトコードに、必要なライブラリなどを付け加えて、実行可能ファイルを生成するプログラムです。コンパイルされたオブジェクトのコードを複数のファイルで取得し、"linked"という一つの実行可能のファイルを生成します。

  • 機械語

    6questions

    機械語とは、プロセッサが直接解釈・実行できる状態の言語です。