2019-2020-1 20199308作品の第2週の「Linuxカーネルの原理と分析」

「Linuxカーネルの解析」

第一章コンピュータの仕事

1.1プログラム内蔵方式ワーキングモデル

  • ノイマン型
    コンピュータアーキテクチャのさまざまな「客観法律」を遵守する必要があります
    • Structureチャート

    • コアノイマン型は、プログラム内蔵方式です。
    • 命令やデータを保持するためのメモリ、CPUはバスによって相互に接続され、これらの命令を、解釈し、実行する責任があります。
      プログラム内蔵方式の模式図

    • x86-32コンピュータのために、EIPは、メモリ命令にポイントを登録し、EIPは、一つ(命令を追加)だけインクリメントされます。

1.2 x86-32アセンブラの基礎

1.2.1 x86-32 CPUレジスタ

  • Eレジスタは、典型的には、32ビットを開始します。
  • 32ビットは、EAX、EBX、ECX、EDXとだけでなく、データを送信することができ、一時的なデータは、算術論理演算の結果を保存し、それはポインタレジスタとしても使用することができるレジスタ。
  • セグメントレジスタ
  • スニペット:CSを使用して:EIPを正確に次の命令のメモリアドレス指定(コード内のコードセグメントを知るために、すなわち、最初の必要性を、次いでコードセグメントEIPにおける命令アドレスの相対オフセットを知る必要があります)。

  • スタックセグメント:各プロセスは独自のスタックセグメントを持っています。
  • リボンRの先頭を指すは、64ビットレジスタです。

    1.2.3一般的なアセンブリ命令とアドレッシングモード

  • 最も一般的には、アセンブリ命令のmov命令は、MOVB手段8であり; MOVW手段16; MOVL手段32; MOVQ 64を意味します。
  • アドレッシング
  • x86-32ほとんどの命令は直接メモリにアクセスすることができますが、そのようなので、上のMOV、プッシュ/ポップととして直接メモリ操作にはいくつかの命令が、あります。
  • プッシュ:PUSHLプッシュ32が示されています。
pushl %eax

EAXレジスタ・スタックの値がスタックに押されています。実際には二つの動作:
①ESPの値がスタックマイナス4をスタックに登録します。スタックが下方に成長するので、SUBL減算命令を使用するので、それは、確保されたメモリセルスタックです

subl $4, %esp

②間接アドレッシングは、次にESPアウト確保されたメモリセルへのポイントを登録ESPレジスタポイントに登録EAXの値を配置することです。

movl %eax, (%esp)
  • スタック:
popl %eax

EAXは、スタックの位置からスタックに登録し、スタックから1つのメモリセルスタックを取ります。実際には二つの動作:
①スタックの最上部にEAXレジスタの値。

movl (%esp), %eax

スタック上方バックオフ一つのメモリセルの位置に対応する命令②ADDLプラス4とスタックの上部、すなわちスタック収縮。

addl $4, %esp

各実行スタックが成長しているスタックが収縮されPUSHL命令は、命令がPOPL実行します

  • コール命令は、関数呼び出し、2つの動作の等価です。
push %eip
movl f %eip
  • これは、関数の戻り命令RETです
  • EIPとプログラマが直接、間接的に修飾された専用の命令(例えば、通話、RETのJMPなど)を変更することはできません。

1.2.4アセンブリコードの例構文解析

以下の2つの断片を変更の効果と同じです

次の断片が少し複雑です(ブックP12)

1.3シンプルなC言語プログラムをコンパイルし、そのアセンブリ命令の実行を分析

  • ビューに「LS」コマンド

vi main.cVIMエディタmain.cのファイルを開くためのコマンド

gcc main.cコマンドは直接コンパイルし
echo $?、このプログラムの戻り値をチェックするためのコマンドを

gcc -S -o main.s main.c -m32アセンブリコードにコマンドにコンパイルのmain.c
とVIMエディタで
g/\.s*/dすべての追加情報を削除するためのコマンド、「クリーン」なアセンブリコードへのアクセス

  • 上述した「クリーン」なアセンブリコードの分析
1 g:
2   pushl   %ebp  //将EBP压栈,将位置4存到位置7;ESP也指向位置7。
3   movl    %esp, %ebp  //将EBP也指向位置7。
4   movl    8(%ebp), %eax  //EBP变址寻址,加8,即指向位置7不动,并把位置5的内容(即立即数8)放入EAX(取出函数g的参数)。
5   addl    $3, %eax  //将立即数3加到EAX中,即8+3,EAX为11。
6   popl    %ebp  //将位置7的内容(即位置4)放回EBP(即恢复函数f的函数调用堆栈基址EBP),即EBP指向位置4;【同时ESP加4,指向位置6】。
7   ret  //(popl%eip)将ESP所指向的内容,即行号15放入EIP,即EIP指向行号15;同时ESP加4,即指向位置5。
8 f:
9   pushl   %ebp  //将EBP向下移动(从EIP的位置3开始),指向位置4。
10  movl    %esp, %ebp  //将ESP也指向EBP的位置4。
11  subl    $4, %esp  //ESP减4,指向位置5。
12  movl    8(%ebp), %eax  //EBP变址寻址8,向上移动两个存储单元即加两个标号的位置,即指向位置2;并将位置2存储的立即数8放到EAX中。
13  movl    %eax, (%esp)  //将EAX放入ESP中,即立即数8放入位置5。
14  call    g  //类似第22行,将ESP指向位置6,;把EIP行号15放到位置6,并指向函数g的位置即第2行。
15  leave  //撤销函数堆栈,等价于=(movl %ebp,%esp和popl %ebp),即将EBP的内容(位置4)放入ESP,即ESP也指向位置4;【然后把位置4的内容(即位置1)放回EBP,即EBP指向位置1;同时ESP加4,指向位置3。】
16  ret     //将ESP所指向的位置3的内容(即行号23)放到EIP中,即EIP指向行号23,;同时ESP加4,指向位置2。 
17 main:
18  pushl   %ebp  //开始执行第一条指令,EIP自动加1即指向行号19;把EBP的值压栈,先将EBP指向位置1,再将EBP的值标号0。
19  movl    %esp, %ebp  //EIP自动加1即指向行号20;将EBP指向位置1。
20  subl    $4, %esp  //EIP自动加1即指向指向行号21;将ESP减4,即向下移动,指向位置2。
21  movl    $8, (%esp)  //EIP自动加1即指向行号22;把立即数8放入ESP,仍指向位置2(20和21行同作为压栈f函数所需参数)。
22  call    f  //执行此行时,EIP已经自动加1指向了下一行即指向行号23(pushl %eip),然后将函数f的开始指令放入EIP(movl f %eip),即EIP指向函数f的位置即第9行。
23  addl    $1, %eax  //将EAX加立即数1,即11+1,EAX的值为12,(EAX是默认存储函数返回值的寄存器)。
24  leave  //撤销函数main堆栈,将EBP和ESP都指回位置1,【同时把位置1存储的内容(即位置0)放到EBP,即EBP指向位置0;并ESP加4,也指向位置0】。
25  ret  //指令结束。

[]はかなり全体の内容を理解していませんでした

  • 休暇命令順序は同等です:
movl %ebp,%esp
popl %ebp
  • 命令を入力することに相当します。
pushl %ebp
movl %esp, %ebp

おすすめ

転載: www.cnblogs.com/hsj910/p/11563286.html