linux内核分析之-x86汇编原理
2016-02-24 23:23
579 查看
linux内核分析之-x86汇编原理
作者:郎勇前言
冯·诺依曼提出了在数字计算机内部的存储器中存放程序的概念(Stored Program Concept),这是所有现代电子计算机的范式,被称为“冯· 诺依曼结构”,按这一结构建造的电脑称为存储程序计算机(Stored Program Computer),又称为通用计算机。冯·诺依曼计算机主要由运算器、控制器、存储器和输入输出设备组成,它的的特点是:程序以二进制代码的形式存放在存储器中;所有的指令都是由操作码和地址码组成;指令在其存储过程中按照执行的顺序(摘自百度百科);学习汇编,有助于我们更好地理解通用计算机的运行原理,因此无论在我们的学习和工作中是否会涉及到汇编,了解汇编的基本知识,对开阔我们程序开发人员的视野,是大有帮助的。编写本博客的初衷是为了完成网易云课堂的随堂作业,希望自己在编写本博客的过程中,对x86汇编原理获得更深一步的认识,与此同时,也希望能帮助所有看到这篇博客的人。
对系统学习linux内核感兴趣的同学,可以前往
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
linux内核分析之-x86汇编原理
前言
通用寄存器的类型
常见的汇编指令
一段简单的C程序对应的汇编程序
结论
通用寄存器的类型
16bit | 32bit | desc |
---|---|---|
AX | EAX | 累加器(Accumulator) |
BX | EBX | 基地址寄存器(Base Register) |
CX | ECX | 计数寄存器(Count Register) |
DX | EDX | 数据寄存器(Data Register) |
BP | EBP | 堆栈基指针(Base Pointer) |
SI | ESI | 变址寄存器(Index Register) |
DI | EDI | 变址寄存器(Index Register) |
SP | ESP | 堆栈顶指针(Stack Pointer) |
IP\EIP指令指针寄存器(Instruction Pointer),它可以存放下次将要执行的指令在代码段的偏移量。可以理解为它总是指向下一条将要执行的指令的编号。IP\EIP寄存器通常是不可以直接操作的,通常只能通过jmp、call或者ret等指令进行间接修改。
常见的汇编指令
数据传输指令 MOV, PUSH, POP等程序转移指令 CALL, RET, JMP等
算数运算指令 ADD,SUB,MUL,DIV等
逻辑运算指令 AND,OR,XOR,NOT等
一段简单的C程序对应的汇编程序
我们编写一段简单的c程序int g(int x) { return x + 11; } int f(int x) { return g(x); } int main(void) { return f(3) + 1; }
执行命令
gcc –S –o main.s main.c -m32生成c程序对应的汇编代码
为了方便查看起见,把所有
.开头的行删除,因为这些行是汇编器命令,这里我们并不关心。结果如下:
g: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax addl $11, %eax popl %ebp ret f: pushl %ebp movl %esp, %ebp subl $4, %esp movl 8(%ebp), %eax movl %eax, (%esp) call g leave ret main: pushl %ebp movl %esp, %ebp subl $4, %esp movl $3, (%esp) call f addl $1, %eax leave ret
程序从入口函数main开始分析:
pushl %ebp movl %esp, %ebp
这两句相当于enter指令,用来在程序开头启用新的栈底地址,将之前的堆栈基地址保存到栈顶指向的内存地址中,然后将esp和ebp指针对齐。
subl $4, %esp
将esp向栈顶偏移4个字节的距离
movl $3, (%esp)
将立即数3存储到esp寄存器指向的内存地址中
call f
程序跳转到函数f的入口地址,eip中存放函数f的第一条指令
pushl %ebp movl %esp, %ebp
subl $4, %esp
此三条指令跟main函数的前三条指令完成的功能是一样的。
movl 8(%ebp), %eax
将堆栈基地址向栈底偏移8个字节的长度,内容取出后存储到eax中。此时eax中存储的内容是3。
movl %eax, (%esp)
将eax中的内容(即3)存储到esp对应的内存地址中。
call g
程序跳转到函数g的入口地址,eip中存放函数g的第一条指令。
pushl %ebp movl %esp, %ebp
此三条指令跟main函数和f函数的前两条指令完成的功能是一样的。
movl 8(%ebp), %eax
将堆栈基地址向栈底偏移8个字节的长度,内容取出后存储到eax中。此时eax中存储的内容是3。
addl $11, %eax
将立即数11加到eax中,eax中的内存为14
popl %ebp
弹出esp中的内容,恢复函数f的堆栈基地址
ret
eip恢复为函数g返回后,函数f继续执行的代码段偏移
leave ret
弹出esp中的内容,恢复函数main的堆栈基地址,eip恢复为函数f返回后,函数main继续执行的代码段偏移
addl $1, %eax
将立即数1加到eax中,此时eax的内容为14+1=15
leave ret
弹出esp中的内容,恢复之前调用函数的堆栈基地址,eip恢复为函数main返回后,调用函数继续执行的代码段偏移
结论
计算机的运行过程,就是一个按次序读取存储器中代码指令,然后通过cpu解释并执行指令的过程。执行时所用到的基本数据结构是堆栈。cpu可以直接操作寄存器中的内容。原创作品转载请注明出处
相关文章推荐
- SUSE Linux上安装IPython/Jupyter
- linux命令学习
- linux如何编译和安装infer
- linux 环境变量
- Linux下搭建Wordpress环境
- linux下ppp拨号无线上网
- kali linux 安装 Nessus
- 《 linux后台开发必看书》
- Project Perfect让Swift在服务器端跑起来-在Linux上创建你的Perfect项目(三)
- centos 6 编译安装php-5.4/5.5(lamp模式)
- Linux内核分析 实验一 ——by王玥
- “Linux内核分析”实验报告一
- 《linux内核分析》第一周(2.22~2.28)
- Java开发必会的Linux命令
- linux h264相关
- CentOS6.5下RabbitMQ安装
- Linux中的Buffer 与 Cache
- Linux下忘记密码的前提下进入MySQL数据库
- 制作initrd(6):重做Ubuntu安装盘
- Linux系统硬件信息的查看