冯诺依曼体系结构,就是指存储程序计算机工作模型,计算机系统最最基础性的逻辑结构
从 硬件的角度 看:
CPU中有一个很重要的寄存器IP,可以把它看作是一个指针,总是指向内存的某一块区域(代码段CS),CPU从IP指向的内存地址取一条指令执行,IP自加一,然后再取一条指令执行,IP再自加一
从 程序员的角度 看:
Memory holds instructions and data
CPU interpreter of instructions
把CPU抽象成一个for循环,总是从内存里面取next instruction执行
Q:CPU识别什么样的指令?怎样识别指令?
ABI:程序员与CPU的接口界面
1. 主要是指令的编码(汇编指令),至于汇编指令是怎样编码成二进制的机器指令,这里不作讨论
2. 在这些指令中会使用到一些寄存器,这些寄存器有一些约定
3. 大多数指令可以直接访问内存
基于X86体系结构:
Registers for work space
AX 累加器(Accumulator)
BX 基地址寄存器(Base Register)
CX 计数寄存器(Count Register)
DX 数据寄存器(Data Register)
BP 堆栈基指针(Base Pointer)
SI 变址寄存器(Index Register)
DI 变址寄存器(Index Register)
SP 堆栈顶指针(Stack Pointer)
Segment Register(段寄存器)
CS——代码段寄存器(Code Segment Register),其值为 代码段的段值
DS——数据段寄存器(Data Segment Register),其值为 数据段的段值
ES——附加段寄存器(Extra Segment Register),其值为 附加数据段的段值
SS——堆栈段寄存器(Stack Segment Register),其值为 堆栈段的段值
FS——附加段寄存器(Extra Segment Register),其值为 附加数据段的段值
GS——附加段寄存器(Extra Segment Register),其值为 附加数据段的段值
EFLAGS Register
Memory: more work space
寄存器模式,以 % 开头的寄存器标识符,操作的都是寄存器,和内存不打交道
立即寻址,以 $ 开头的数值,把一个数值直接放到寄存器里,和内存也不打交道
直接寻址,直接访问一个指定的内存地址的数据
间接寻址,将寄存器的值作为一个内存地址来访问内存
变址寻址,在间接寻址之时改变寄存器的数值
Stack memory + operations
Stack grows down
Use to implement procedure calls
函数调用堆栈 是理解C代码在CPU上执行的关键(高级语言得以运行的基础)
(* 号表示eip寄存器不能被直接修改,只能通过特殊指令间接修改)
通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
C程序
gcc –S –o ccode32.s ccode.c -m32
命令将C程序编译成汇编代码
补充:
enter pushl %ebp
movl %esp, %ebp
leave movl %ebp, %esp
popl %ebp
完整汇编程序执行过程分析
Summary:
1. ebp 和 esp 这两个寄存器总是指向堆栈的栈底和栈顶,而这个栈底是相对的栈底。当前函数有一个堆栈,它有一个栈底。跳出这个函数之外的另一个函数,也有自己的堆栈,它也有自己的栈底。由此表明:函数调用堆栈是由逻辑上多个堆栈叠加起来的
2. 函数的返回值默认使用 eax 寄存器存储返回给上一级函数
3. 对能看得见的结构部分(例如,通用寄存器,控制寄存器,状态寄存器,中断或者例外寄存器)的用法,分布和使用约定,或者说编程模式,就是所谓的ABI
(完)