计算机是如何工作的
2017-02-25 20:11
197 查看
存储程序计算机工作模型
冯诺依曼体系结构就是指存储程序计算机从硬件上,CPU和内存由总线连接,CPU上有一个寄存器叫IP(Instruction Pointer),64位下叫rip, 可以认为是一个指针,总是指向内存中的代码段(cs code segment),cpu从IP指向的内存地址取来一条指令执行,执行完后,IP自加一,取下一条指令继续执行。
从程序员来看,内存有指令和数据,cpu抽象成一个for循环,从内存取下一条指令,解释执行指令
32位下, eip每一次自加到下一条指令,因为指令长度是不同的,eip除了可以自加外,可以被call,ret, jmp和条件跳转改变(对应c里的if-else,函数调用,return等)
寄存器
32位下有8个通用寄存器eax 累加器
ebx 基地址寄存器
ecx 计数寄存器
edx 数据寄存器
ebp 堆栈基指针(寄存器)
esi edi 变址寄存器
esp 堆栈顶寄存器
段寄存器
cs 代码段寄存器,其值为代码段的段值
ds 数据段寄存器,其值为数据段的段值
es 附加段寄存器,其值为附加段的段值
ss 堆栈段寄存器,其值为堆栈段的段值
fs 附加段寄存器,其值为附加数据段的段值
gs 附加段寄存器,其值为附加数据段的段值
cpu在实际取指令时根据cs:eip来准确定位一个指令
每一个进程都有自己的堆栈
寻址方式
movl %eax, %edx
edx = eax; 寄存器寻址
movl $0x123, %edx
edx = 0x123 立即寻址,立即数是以$开头的数值
movl 0x123, %edx
edx = (int32_t)0x123 直接寻址 直接访问一个指定的内存地址的数据
movl (%ebx), %edx
edx = (int32_t)ebx 间接寻址 将寄存器的值作为一个内存地址来访问内存
movl 4(%ebx), %edx
edx = (int32_t)(ebx + 4) 变址寻址(displaced) 在间接寻址之时改变寄存器的数值
常用指令
pushl %eax
subl $4, %esp
movl %eax, (%esp)
popl %eax
movl (%esp), %eax
addl $4, %esp
call 0x12345
pushl %eip
movl $0x12345, %eip
ret
popl %eip
eip寄存器不能被程序员直接修改,只能通过特殊指令间接修改
enter
pushl %ebp
movl %esp, %ebp
leave
movl %ebp, %esp
popl %ebp
汇编一个简单的c程序
int g(int x) { return x + 5; } int f(int x) { return g(x); } int main() { return f(3) + 9; }
通过gcc -S -o main.s main.c -m32 生成的汇编的代码,所有以.开头的都是用于链接的辅助信息,不会被实际执行
注释从main函数看起,遇到call x则跳转到该函数x,ret之后返回到call x的下一条指令
内存中栈是从高地址向低地址增长的
从main开始,eip会自动指向吓一跳指令,或者由指令修改
函数调用堆栈是由逻辑上多个堆栈叠加起来的,ebp指向堆栈栈底,esp指向栈顶,堆栈是相对的,因为每个函数都有自己的基地址
函数的返回值默认使用而eax寄存器存储返回给上一级函数
g: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax #将f传来的参数放到eax,即eax = 8 addl $5, %eax #eax = 8 + 3 = 11 popl %ebp #将调用g的函数ebp给pop回来,即ebp指回f的栈基址 ret #popl %eip,此时eip指回调用该函数的下一条指令 f: pushl %ebp #将ebp压栈 movl %esp, %ebp #修改ebp的值,此时ebp和esp指向同一个位置 pushl 8(%ebp) #取ebp+8里的数,即将main调用f时传进的3压栈,相当于subl $4, %eax movl 8(%ebp) %eax movl %eax (%esp) call g #pushl %eip,跳转到g继续执行 addl $4, %esp #对应于上面的pushl 8(%ebp)感觉这句话可以不用,因为下面有个leave leave #把esp指向ebp的位置 ret #popl %eip,eip指回调用它的函数的下一条指令 main: #eip最初指向main pushl %ebp #将ebp压栈 movl %esp, %ebp #修改ebp的值,此时ebp和esp指向同一个位置 pushl $3 #将esp减掉4,然后将3压栈 call f #pushl %eip,此时压入的eip指向的是下一行,然后eip指向了f,跳转到f继续执行 addl $4, %esp addl $9, %eax leave #回到main函数最初的状态 ret #返回到main函数之前的堆栈
总结
计算机系统是由硬件和系统软件组成的,它们共同工作来运行应用程序。虽然系统的具体实现方式随着时间不断变化,大师系统内在的概念没有变化。所有计算机系统都有相似的硬件和软件组件,它们执行着相似的课程。本次课程使我重新复习了汇编程序设计,并对c语言和汇编的对应有了更深一步的了解,让我能更看清楚自己所写的c语言代码在内存中的表示方式。并且从汇编代码看起来,cpu作加载(从主存复制一个字节或者一个字寄存器)、存储(从寄存器复制一个字节或者一个字到主存某个位置)、操作(作算术运算)、跳转等功能,和主存之间的行为通过总线相连。
相关文章推荐
- 企业如何进行计算机取证工作
- 如何让计算机电源独自工作,风扇转起来
- Linux内核分析课程1_计算机是如何工作的
- 图解分析汇编代码以理解计算机是如何工作的
- 反汇编程序分析计算机是如何工作的
- 计算机开机自检是如何工作的
- 从汇编语言角度看C语言代码,理解计算机如何工作
- 浅谈计算机是如何工作的及Linux下的简单反汇编操作
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过分析汇编代码理解计算机如何工作
- 企业如何进行计算机取证工作
- ArcGIS 10.1 for Server修改计算机名称后,如何使Server工作起来
- ArcGIS 10.1 for Server修改计算机名称后,如何使Server工作起来
- Linux学习之路一计算机是如何工作的
- 计算机实际上是如何工作的
- 企业如何进行计算机取证工作 推荐
- 计算机是如何工作的_2
- 计算机是如何工作的(最简单透彻的解释)
- 计算机是如何工作的?
- 《Linux内核分析》MOOC课程之从汇编语言角度看计算机是如何工作的