20135323符运锦----第一周:计算机是如何工作的
计算机是如何工作的
计算机系统是由硬件和系统软件组成的,它们共同工作来运行应用程序。虽然系统的具体实现方式随着时间不断变化,但是系统内在的概念却没有改变。所有计算机系统都有相似的硬件和软件组件,它们执行着相似的功能。一些程序员希望深入了解这些组件是如何工作的,以及这些组件是如何影响程序的正确性和性能的,以此来提高自身的技能。但是,计算机由人发明,这也就决定了它并不会比人聪明。我的观点,计算机其实是十分石板的。你可能会纳闷计算机到底是如何工作的,其实非常简单,就是不断地取出指令和运行指令,最后将结果返回至已指定的存储器地址之中。如果还有下一条指令的继续到来,那么重复上述要求就可以了。所以,计算机是十分简单的,但是很多简单的事情越做越不简单,难的事情越做越简单。归根结底,我们还是需要深入地去了解计算机是如何工作的。
听课记录
冯诺依曼体系结构:即具有存储程序的计算机体系结构。目前大多数拥有计算和存储功能的设备其核心构造均为冯诺依曼体系结构。从硬件来看:CPU与内存通过主线连接,CPU上的IP(可能是16、32、64位)总指向内存的某一块区域;IP指向的CS(代码段)也在内存中;CPU总是执行IP指向的指令。从软件来看:API(应用程序编程接口,与编程人员)与ABI(程序与CPU的借口界面) 是两个比较重要的软件接口。
ABI:指令编码。大多数指令可以直接访问内存。
汇编指令
leave指令与enter指令一起相当于两条宏指令
movl %ebp,%esp
popl %ebp
pushl %ebp
movl %esp,%ebp
popl %eax:###
将栈顶的数值放入eax里面。
ret:###
将函数调用时候保存的eip出栈,执行函数调用之后的下一条指令。
寻址方式
寄存器寻址
movl %eax,%edx
与内存无关,相当于eax=edx
立即寻址
$+,将数值直接放进寄存器当中,与内存无关。
$0x123,%edx:123这个16进制数值放进寄存器edx之中。
直接寻址
一个16进制数字表示一个地址。
0x123,%edx:123这个地址指向寄存器edx。
间接寻址
寄存器的值表示一个内存地址,将这个内存地址中的值放进寄存器中。
(%ebx),%edx:(%ebx)表示ebx这个寄存器存的值为内存地址。
变值寻址
括号外面的数字表示寄存器地址加一个立即数。
实验部分
代码如下:
编译后的代码如下:
精简后代码为:
addr:
pushl %ebp//ebp(4)压栈
movl %esp, %ebp//将ebp指向位置7
movl 8(%ebp), %eax//将位置5的9赋给eax
addl $7, %eax//eax+7=16
popl %ebp//弹栈,esp-4指向位置6
ret//即pop %eip,eip指向15
f:
pushl %ebp//将ebp(1)压栈,esp指向下一个位置。
movl %esp, %ebp//将ebp指向位置4
subl $4, %esp//esp-4,指向下一条
movl 8(%ebp), %eax//ebp变值地址为8,指向位置2,所以eax=9
movl %eax, (%esp)//把eax放入esp对应位置,即位置5
call addr//eip(15)压栈,此时指向addr.esp指向下一条
leave//ebp弹栈,指向位置1,esp+4到位置3
ret//同上,esp+4,指向位置2
main:
pushl %ebp//ebp入栈,并保存ebp(0)。esp-4,指向下一条
movl %esp, %ebp//将ebp指向位置1
subl $4, %esp//esp-4,指向下一条
movl $9, (%esp)//将立即数9放在esp指向的位置中去,即位置2
call f//eip随即指向下一条指令,将eip压栈。指令执行f,esp指向下一条
addl $1, %eax//eax+1=17
leave//包含movl %ebp,%esp 与popl %ebp两条指令。开始均指向位置1,后回到初始状态,即都指向位置0
ret
详细过程:
符运锦 原创作品转载请注明出处 《Linux内核分析》MOOC课程
http://mooc.study.163.com/course/USTC-1000029000