2019-2020-2 20199317 "Linux kernel principle and Analysis" in the second week of work

The first chapter Computers Work

1 stored program computer working model

     The main idea is to stored program computer program stored in computer memory, and then the first address by executing the program stored in the program memory of the first instruction, since you write good instruction is executed in the program until the end of the program execution.

        The core von Neumann architecture is a stored program computer.

2 x86-32 assembler basis

    8086CPU in a total of 14 16-bit registers (AX, BX, CX, DX, SP, BP, SI, DI, IP, FLAG, CS, DS, SS and ES), then the corresponding has 32-bit registers (EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI, EIP, EFlags, CS, DS, SS, ES, FS, and GS) 32-bit register just extend the corresponding 16-bit register to 32 bits, and all beginning with E memory, typically 32 bits.

       It is noted that in the 16-bit CPU in, AX, BX, CX and DX not be used as base address and index registers to store addresses of memory cells, but in the 32-bit CPU, a 32-bit register EAX, EBX, ECX, and EDX can not only transmit data, temporary data save arithmetic logic operation result, can also be used as a pointer register, these registers 32 more versatile.

       To 32 mainly describes some common assembly instructions:

       Register Addressing : movl% eax,% edx;

       Register addressing operation is a register, memory, and not to deal with, EAX%, wherein after the opening with a register name%. The meaning of the above code is the register contents into% eax in% edx.

       Addressing immediately : movl $ 0x123,% edx

       The code means the hexadecimal 0x123 this value directly into EDX register. Addressing memory and also does not matter now.

       Direct Addressing : movl 0x123,% edx

       The code is the meaning of the data points to the memory address 0x123 piece of memory stored into EDX register. Direct addressing data is directly accessible by memory address in memory.

       Indirect : movl (% ebx),% dx

       Register indirect addressing is to add a small brackets. The code means% ebx value stored in this register is a memory address, add a small brackets indicate the data stored in this memory address, we put it into EDX register.

       Indexed addressing : movl 4 (% ebx), % edx

       Code "(% ebx)" there is a 4 in front, i.e. on the basis of indirect addressing, in the original address plus a 4 number immediately.

       Another point to note that, in general, all uppercase letters are generally Intel assembly, all lowercase letters are generally AT & T assembler. Here register the code name used comply with the way AT & T assembler format all-lowercase.

       Next comes a few very important instruction: pushl / popl and call / ret.

       AT & T in the compilation, pushl assembly instructions equivalent to the following:

. 1 subl $ 4 , # ESP% of the value of the stack minus the ESP register stack 4, because the stack grows downwards
 2 Movl EAX%, (% ESP) # EAX register into the value of the ESP register points to the place

        AT & T in the compilation, popl assembly instructions equivalent to the following:

. 1  Movl (ESP%), the value of #% EAX EAX register into the top of the stack
 2 of ADDLs $ 4 , plus 4% ESP # stack, the stack is equivalent to a position upwardly rollback storage unit

       AT & T in the compilation, Call instruction is a function call, a call address, for example, call 0x12345 assembly instructions equivalent to the following:

1  pushl% EIP (*) # push the current EIP register
 2 movl $ 0x12345, EIP% (*) # 0x12345 to this number immediately put EIP register

      Then special note here, the above operation does not exist actually corresponds to two instructions herein with "(*)" to look specially marked, two actions are done by hardware disposable, but for security reason, EIP register can not be modified and used directly.

      AT & T in the compilation, RET instruction with the instruction corresponding to the call, a function return instruction, the instruction RET is equivalent to the following compilation:

. 1 popl% EIP (*) # the current top of the stack a stack of storage units into the EIP register

      Also here there is no operation command corresponding to the actual, this action is finished disposable hardware.

3 assemble a simple C language program analyzed and assembly instructions execution

      Enter the ls command to see the "Code" and "LInuxKernel", because the directory "Code" in accordance with "experimental building" the convention is to use the directory to save the user to write code, so the next "Code" directory to operate.

        

        The C code used in the experiment are:

 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语言程序,最后自己分析了汇编代码是如何在存储程序计算机工作模型上一步步执行的。

        

      

 

Guess you like

Origin www.cnblogs.com/chengzhenghua/p/11564233.html