セクションについて

gccによってコンパイルされたアセンブリソースを眺めていると、そこかしこに .text だとか .ascii だとか書かれているのを見かける。これらは一体なんなのさ、ということについて調べた。ピリオドで始まるこれはディレクティブと言うもので、様々な意味を持っている。
まずは、そのディレクティブの一つの用法であるセクションについて説明する。


C言語のプログラムをgccにてコンパイルしたときの動きについて、まずは復習しよう。
はじめにソースコードに対してプリプロセッサが働いてコンパイルできる状態にし、続いてコンパイラによってアセンブリソースが吐かれる。そのアセンブリソースはasというアセンブラによってアセンブルされてオブジェクトファイルになる。最後に、それらのオブジェクトファイルがldというリンカによってリンクされ、実行形式のファイルになる。


これから確認されるように、アセンブラアセンブリ言語のソースからリンク可能なファイル(=オブジェクトファイル)を作成するという機能を持っている。
だから何なのか、というと、つまりはそういうことで、アセンブリソースの中にある各種記号は全てリンク可能ファイルを作成するためにあるってこと。それがディレクティブがここにある理由。あなたがここにいる理由。


リンク可能ファイルはのっぺりとしたバイナリではなく、プログラムになったときに

  • プログラムとして動作するバイナリ領域
  • 変数として予め確保するもののうち、初期値を持つもののための領域
  • 変数として予め確保するもののうち、初期値を持たないもののための領域

の三種類の領域に分かれるように作られてる。
ひとつめをtextセクションと呼ぶ。これはコードを保持するためのセクションなので、基本的に実行可能・書換不可能に設定される。
ふたつめをdataセクションと呼ぶ。これはグローバル変数など、実行前から確保することが分かっている変数で、かつ初期値を持つもののための領域。もちろん書換可能。
みっつめをbss セクションと呼ぶ。これは初期値を持たないものに対して確保する領域で、書換可能。初期値に自動的にゼロが代入されるという約束があるので、実行ファイルの容量をその指定分だけ減らすことが出来る。
これらのセクションに一切のデータを入れないことも出来るけれど、自動的に容量ゼロで作成されるらしい。*1
この三つ以外で使われるものとして、rodataセクションがある。これは書換不可能な領域で、固定文字列などの保持に使われる。


asは、具体的にこれらのセクションを指定するレベルでコーディングするの。

.section ディレクティブ

.section ディレクティブを利用すると、その指定以降の部分(コードなり変数なり)を置くセクションを指定することが出来る。たとえば、

.section .text
movl $100, %eax
addl -4(%ebp), %eax
...

とすれば、movl以降の文はtext segment上に置かれることになる。
.text .data .bss など以外の適当な名前を .section の後ろに書いた場合、そういう名前のセクションを作成して、そこに配置してくれる。
ちなみに、セクション名等に設定できるシンボルは、$か.か_か[a-zA-Z]で始まって、$か_か[a-zA-Z0-9]が任意の数並ぶもの、と決められてる。とすると$$$$とか____とかもシンボルとして定義できることになる。マジで!?あとで試す。

サブセクション (Sub-Sections)

アセンブリコードの中で離れていても、一続きに配置されて欲しいことがある。そういうときはサブセクションを使う。
サブセクションは、セクションの中での配置の順番を決めることが出来る機能だ。一つのセクションの中での配置の順番を決めたいときに使える。例えば

.text 0
.ascii "This lives in the first text subsection. @@"

.text 1
.ascii "This lives in the second text subsection."

.data 0
.ascii "This lives in the first subsection "
.ascii "of the data section."

.text 0
.ascii "This lives in the first text subsection,"
.ascii "right after the @@ ."

とすると、.text 0 のものは .text 0 にまとめられ、それに .text 1 が続く。
書き方は上に示したとおり、section name + Sub-section number とすれば良い。


アセンブラソースって言う方が一般的なのかな?アセンブラ(as)のソースって意味に見えちゃうので遠慮してアセンブリソースって書いてるんだけど、用法として問題ありそうなら変更します。みょん。

*1:参考URL;info asの内容と思われる