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

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

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

     主なアイデアは、コンピュータメモリ内に格納されて格納されたプログラムコンピュータプログラムであり、その後、あなたが良い命令を記述しているので、最初の命令のプログラムメモリに格納されたプログラムを実行することによって、最初のアドレスは、プログラムの実行が終了するまで、プログラム内で実行されます。

        コアノイマン型は、プログラム内蔵方式です。

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

    14の16ビット・レジスタ(AX、BX、CX、DX、SP、BP、SI、DI、IP、FLAG、CS、DS、SS及びES)の合計8086CPU、対応する32ビット・レジスタ(EAXを有しますEBX、ECX、EDX、ESP、EBP、ESI、EDI、EIP、EFLAGS、CS、DS、SS、ES、FS、及びGS)32ビット・レジスタは、単に対応する16ビットEと32ビット、およびすべての先頭に登録伸びますメモリ、典型的には32ビットです。

       ベース・アドレス及びインデックスとして使用されていないAX、BX、CX、およびDX、16ビットCPUのメモリセルのアドレスを格納するレジスタに留意するが、32ビットCPUで、32ビットEAX、EBX、ECX、および登録されていますEDXは、データを送信する一時的なデータは、算術論理演算の結果を保存し、また、これらのレジスタは32より多目的な、ポインタ・レジスタとして使用することができるだけでなく。

       32主に、いくつかの一般的なアセンブリ命令について説明します。

       アドレッシング登録:MOVL%eaxに、%EDX;

       操作に対処登録は前記レジスタ名%で開封後、に対処するためのレジスタ、メモリ、およびない、EAX%です。上記のコードの意味は、%EDXの%eaxレジスタにレジスタの内容です。

       すぐにアドレス指定:%EDX、$ 0x123をMOVL

       コードは、EDXレジスタに直接進0x123にこの値を意味します。メモリアドレッシングとも今は関係ありません。

       直接アドレス指定:0x123をMOVL、%EDX

       コードは、EDXレジスタに格納されたメモリのメモリアドレス0x123片へのデータポイントの意味です。ダイレクトアドレッシングデータは、メモリ内のメモリアドレスによって直接アクセス可能です。

       間接:MOVL(%のEBX)、% DX

       間接アドレスを登録すると、小さなブラケットを追加することです。コードは、このレジスタに格納されている%のEBXの値を意味するメモリアドレスである、小さなブラケットは、このメモリアドレスに格納されたデータは、我々はEDXレジスタに入れて示している追加。

       アドレッシングインデックス付け:MOVL 4(%のEBX)、 %EDX

       コード「(%のEBX)」フロント4、すなわち、元のアドレスに加え、直ちに4数で、間接アドレッシングに基づいて、存在します。

       一般的には、すべての大文字は、一般的にインテルのアセンブリであることは注意すべきもう一つのポイントは、すべて小文字は一般的にAT&Tアセンブラです。ここではAT&Tアセンブラフォーマットすべて小文字の方法に準拠して使用されるコードネームを登録します。

       PUSHL / POPLおよび/ RET呼び出し:次のいくつかの非常に重要な指示をしています。

       コンパイル中にAT&T、以下に相当PUSHLアセンブリ命令:

1 SUBL $ 4 、スタックの値マイナスESPレジスタスタック4の#1のESP%、スタックが下方に成長するので、
 2 MOVL EAX%と、(%ESP)#1 EAX場所にESPレジスタ点の値にレジスタ

        コンパイル中にAT&T、以下に相当POPLアセンブリ命令:

1  MOVL(ESP%)、#の値%EAX EAXスタックの最上位に登録
 2のADDL $の4プラス4%ESP位スタック、スタックが位置上向きにロールバックの記憶手段に相当します

       コンパイル中にAT&Tは、CALL命令が関数呼び出し、呼び出しアドレスで、例えば、次のように相当0x12345アセンブリ命令を呼び出します。

1  PUSHL%はEIP(*)#現在のEIPレジスタを押す
 2この番号にMOVL $ 0x12345、EIPの%(*)#0x12345をすぐにEIPレジスタを置きます

      そして、特別な注意はここで、実際には存在しないような動作は、本明細書では「(*)」に特別マーク見えるように、二つの動作は、ハードウェア使い捨てで行われますが、セキュリティのためにしているとの2つの命令に対応しますその理由は、EIPレジスタは変更され、直接使用することはできません。

      コンパイル中にAT&T、コールに対応する命令、関数の戻り命令とRET命令は、命令RETは、次のコンパイルと同等です。

1 POPL%のEIP(*)#スタックの現在のトップEIPレジスタに記憶ユニットのスタック

      またここでは、実際、このアクションが終了した使い捨てのハードウェアに対応する操作コマンドがありません。

3分析され、簡単なC言語プログラムとアセンブリ命令の実行を組み立てます

      LSはディレクトリ「コード」は「実験的な建物」に従って規則は、コードを書くために、ユーザーを保存するディレクトリを使用するので、動作するように、次の「コード」ディレクトリので、「コード」と「Linuxカーネル」を参照してコマンドを入力します。

        

        実験に用いたCコードは、次のとおり

 1 // main.c
 2 int g(int x)
 3 {
 4     return x + 4;
 5 }
 6 
 7 int f(int x)
 8 {
 9     return g(x);
10 }
11 
12 int main(void)
13 {
14     return f(6) + 1;
15 }

         在命令行下输入" vi  main.c"命令打开文本编辑main.c文件,按"i"键进入输入状态,如下图所示:

         

        接下来在文本编辑器VIM中按“Shift” + “:”进行文本编辑的命令模式,输入“wq”就可把代码保存到main.c中,并退出VIM编辑器,但是我遇到了一个问题就是在插入模式下按照前边操作是无效没有反应的,我的解决方案是:按ESC退出编辑模式,此时的模式为“NORMAL”模式,然后再输入冒号,接着输入“wq”,再按回车键即可,如下图所示:

         

        然后使用gcc main.c命令编译main.c这个代码文件,这时会生成一个目标文件a.out,它是可执行的,但此时看不到任何信息,可以通过echo $?命令查看这个程序的返回值,该C语言程序的结果为11,如下图所示:

         

       接着可以把main.c编译成一个汇编代码,可使用gcc -S -o main.s main.c -m32这个命令,如下图所示:

         

        此时我们可以看到main.s汇编文件还有一些“.cfi_”打头的字符串以及其他以“.”打头的字符串,这些都是编译器在链接阶段所需的辅助信息,可以通过在VIM中输入“g/\.s*/d”命令删除所有以“.”打头的字符串简化main.s里的汇编代码,注意在这里VIM编辑器要在“NORMAL”模式下输入“:”,再输入“g/\.s*/d”命令,按回车键即可,如下图所示:

          

         接着我介绍一下在上面main.s文件中新出现的汇编指令leave指令,还有与leave指令相对应的enter指令。

         leave指令用来撤销函数堆栈,等价于下面两条指令:

1 movl  %ebp,  %esp
2 popl  %ebp

          enter指令用来建立函数堆栈,等价于下面两条指令:

1 pushl  %ebp
2 movl  %esp,  %ebp

        最后对该C语言程序的汇编代码进行分析:

         首先假定堆栈为空栈的情况下EBP和ESP寄存器都指向栈底,而且为了简化起见,我们为栈空间的存储单元进行标号,压栈时标号加1,出栈时标号减1,如下图所示:

          

 

        下面是我的分析过程:

          

 

          

          

        我在分析汇编代码时movl  8(%ebp),  %eax中的间接寻址产生了一个误区:我以为使用ESP寄存器变址寻址,是ESP寄存器向上移动两个标号,导致我后边的分析出了差错。后来翻看课本对间接寻址的定义,才知道是EBP寄存器存储的数值加8,ESP寄存器不移动。

4   总结

       在本次学习中,我通过课本,再一次回顾了存储程序计算机工作模型以及基本的一些的汇编语言,重点是再一次深入理解了函数调用堆栈相关汇编指令,如call/ret和pushl/popl,还有leave和enter,并通过自己动手实践将一个C语言代码程序在Linux环境下运行,同时反汇编C语言程序,最后自己分析了汇编代码是如何在存储程序计算机工作模型上一步步执行的。

        

      

 

おすすめ

転載: www.cnblogs.com/chengzhenghua/p/11564233.html