2013-07-27 15 views
19

これは私のアセンブリレベルのコード...アセンブリ言語でグローバル_startとは何ですか?

section .text 
global _start 
_start: mov eax, 4 
     mov ebx, 1 
     mov ecx, mesg 
     mov edx, size 
     int 0x80 
exit: mov eax, 1 
     int 0x80 
section .data 
mesg db  'KingKong',0xa 
size equ  $-mesg 

出力:

[email protected]:~/Arena# nasm -f elf a.asm -o a.o 
[email protected]:~/Arena# ld -o out a.o 
[email protected]:~/Arena# ./out 
KingKong 

私の質問は、グローバル_startがのために使用されている何ているのですか?私はMr.Googleと運が良かったと思っていました。プログラムの出発点を伝えるために使用されていました。なぜカント私達はちょうどプログラムが画面

section .text 
_start: mov eax, 4 
     mov ebx, 1 
     mov ecx, mesg 
     mov edx, size 
     int 0x80 
exit: mov eax, 1 
     int 0x80 
section .data 
mesg db  'KingKong',0xa 
size equ  $-mesg 

[email protected]:~/Arena# nasm -f elf a.asm 
[email protected]:~/Arena# ld -e _start -o out a.o 
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048080 
[email protected]:~/Arena# ld -o out a.o 
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048080 
+1

アセンブリ内の "global main"(http://stackoverflow.com/questions/17882936/global-main-in-assembly) –

答えて

25

globalディレクティブにちょっと 警告を生成下記いずれかのよう始まる_startを伝える必要がありますすることはNASM固有のものです。これは、コード内のシンボルを、生成されたオブジェクトコードを指し示す場所にエクスポートするためのものです。 _startシンボルはグローバルなので、その名前がオブジェクトコード(a.o)に追加されます。リンカ(ld)は、オブジェクトコードとその値の中のそのシンボルを読み取ることができるため、出力実行可能ファイルのエントリポイントとしてマークする場所を知ることができます。実行可能ファイルを実行すると、コード内で_startとマークされた場所から開始されます。

シンボルに記号がない場合はglobalディレクティブがオブジェクトコードのエクスポートテーブルに配置されないため、リンカはシンボルについて知る方法がありません。

あなたは(デフォルト)_startとは異なるエントリポイント名を使用する場合のように、あなたはldに-e parametreを指定することができます:あなたはそれを宣言するまで、ラベルが明示的にグローバルではありません

ld -e my_entry_point -o out a.o 
+1

'_start'はデフォルトでldが"知っている "ものです。 'ld -o out a.o -e _main'が動作します。 –

+0

私の質問を少し変えてから、私の質問は私の音をもう少しクリアにします... – vikkyhacks

+0

@vikkyhacks私の答えは明確ではありませんか?あなたの質問は変わっていないようです。 –

2

グローバルであれば、グローバルディレクティブを使用する必要があります。

グローバル_startはリンカによって必要とされます。グローバル_startアドレスがない場合、リンカは見つからないため文句を言います。 _startをグローバルとして宣言しなかったので、そのモジュール/オブジェクトのオブジェクトの外側には表示されず、リンカーには表示されません。

これは、あなたがハローと楽しいが、グローバルオブジェクトの外からも見えますが、この

static unsigned int hello; 
static int fun (int a) 
{ 
    return(a+1); 
} 
ある

unsigned int hello; 
int fun (int a) 
{ 
    return(a+1); 
} 

ローカルであることを宣言しない限り、物事がグローバルであることを暗示しているCの反対であります

はローカルには見えません。

すべてのローカル:これらは今

global _start 
_start: 
global hello 
hello: 
... 
+0

これらの指令はアセンブラ固有のものであり、アセンブラはアセンブリ言語を機械語にアセンブルするプログラムです。アセンブリ言語は一般的に標準を持っていないので、各アセンブラは独自のことを行うことができます。 "intel format"と "at&t format"は同じ命令セットの極端なものです。同様に、いくつかは「グローバル」が必要な場合があり、他の場合は「グローバル」が必要な場合があります。したがって、必ずしも命令セットではなく、ツールチェーンのニュアンスを学んでいます。 –

+0

実際にそれを消化することは非常に難しくなります。私たちは、使用されている関数のためにC言語でローカル変数とグローバル変数という概念を持っていますが、アセンブリ言語のスコープがあります(間違っていれば正しいアセンブラ)なぜリンカは私のプログラムの_startを検索し、実行の開始点を設定するだけですか?それにはどんな情報が欠けていますか? – vikkyhacks

+1

@vikkyhacks、私はあなたが少なくともデフォルトでは、Cのコンテキストで "静的"シンボルとしてアセンブリ内のラベルを考えることができると思います。つまり、ファイル/翻訳単位の範囲でのみ使用できます。 '.global'でラベルを定義すると、アセンブラはそれをエクスポートして(オブジェクトのシンボルテーブルに追加して)、リンカが他の翻訳単位(またはあなたの場合はプログラムのスタートアップ)で使用できるようにします。 –

1

_startリンカーおよび他のオブジェクトに利用できるグローバルな

_start: 
hello: 
fun: 
more_fun: 

がデフォルトldリンカスクリプトによって設定されます。

ld -verbose a.o | grep ENTRY 

出力:

ENTRY(_start) 

ELF file format(と私が推測する他のオブジェクト形式)は、プログラムがどのアドレスをe_entryヘッダーフィールドで実行し始めるかを明示します。

ENTRY(_start)は、オブジェクトファイルからELFファイルを生成するときに、そのエントリにシンボル_startのアドレスを設定するようにリンカに指示します。

OSがプログラムの実行を開始すると(Linuxの場合exec system call)、ELFファイルを解析し、実行可能コードをメモリにロードし、命令ポインタを指定されたアドレスに設定します。

-eフラグがby Sedatと記載されていると、デフォルトの_startシンボルが上書きされます。

デフォルトリンカースクリプトを-T <script>オプションに置き換えることができます。

+0

'ld -o a.o'は単に「入力ファイルがありません」と言います。どのようなコマンドラインオプションを意味しましたか? –

+0

@PeterCordesありがとう!私は ''大胆さ 'を意味すると思う。 –

0

global _startは、メモリアドレスを指すラベルです。_startの場合、ELFバイナリには、プログラムが開始されるアドレスとして機能するデフォルトのラベルが使用されます。

mainまたは_mainまたはmain_もありますが、C言語に知られており、「通常」にリンクされている「スタートアップコード」で呼ばれている - あなたはC.

・ホープこのことができますを使用している場合。