上图是cpu中三个组成部分:寄存器 運算器 控制器
DS,SSCS,ES其中ds,ss,cs,es是段寄存器。段寄存器什么意思呢
通用寄存器的作用:存放一般性的数据在各种指令中都可以见到,movadd,subxor等等
BP:base pointer,其内存放着一个指针该指针永远指向系统栈朂上面一个栈帧的底部。
SP:stack pointer其内存放着一个指针(也就是地址),该指针永远指向系统栈最上面一个栈帧的顶部
(高地址)| ``````````````| <---bp指向当前嘚栈帧的底部——当函数的调用后,在函数的出栈入栈过程中进行保存
等价于先弹出栈顶寄存器指向的地址存的值 [esp]->eax再增加栈顶寄存器,往上移esp=esp+4
ebp在某个函数执行过程中是固定的变用来寻找在栈参数与变量。
ebp在函数的调用过程发生改变而在函数执行结束之后需要还原,因此需要在函数的出栈入栈过程中进行保存。
mov 寄存器寄存器/数据/内存单元
mov 内存单元,寄存器
注意:一般把某个寄存器清零会用xor eax,eax用異或,而不是mov eax0,前者效率高
add 寄存器,寄存器/数据/内存单元
add 内存单元,寄存器
如何记住一个二进制数据左移1位相当于乘以2左移n位,楿当于乘以2的N倍:
一个10进制的数左移1位相当于乘以10,左移n位相当于乘以10的N倍。
是最关键的两个寄存器代码段寄存器和指令指针寄存器 ,他们的内容提供了cpu要执行指令的地址
而cpu就是一直重复读指令,执行指令的过程cpu就认这个指向的地址为指令,然后进行执行指令所以把 代码段的起始地址设置成cs:ip,让程序开始执行
1:从cs:ip(段地址的方式)指向的内存单元中读取指令,读进来以后进入指令缓存器
2:ip = ip + 所读指令的长度从而指向下一条指令
1. 怎么知道指令的长度的
2.什么时候修改cs 和 ip 的值的 (下面介绍)
用来改变cs和ip的值嘚指令,CS*16 + IP 指向的内容被当作指令来执行
jmp 某一个合法寄存器——改变IP的值
用这个寄存器的值改变IP寄存器的值含义上[ mov IP寄存器,某一合法寄存 ] 只不是mov不能用于IP寄存器。
jmp 段地址:偏移地址——同时修改CS的值和IP的值
位机、 8086 16位机。8086的cpu16位地址总线20位,给物理地址的方式(20位) = 段地址(16位)*16(左移4位) + 段内偏移(16位段最大长度是2^16 = 64k))
32位cpu 也可以开启36位地址模式,所以也可以用用 36位物理寻址方式=段地址(32位)*16(左移四位) +段内偏移(32位段最大长度是2^32 =4G)
所以一个段的其实地址一定是16的倍数(16进制表示,最后一位肯定是0)
所以看的地址 也是 使用的段+段内偏移只不是那个段是指的是段号。
存放要访问的数据的段地址再通过加上偏移地址,把数据所在的内存地址赋值上
通过move指令进行设置其值,先把其值赋值给一般寄存器再通过一般计算器传送给DS
move al,[0]————访问到了ds:0所指的内存单元了
任意时刻ss:sp指向栈顶元素的内存地址。
cpu不保证对栈的操作不超过空间
cpu只知道栈顶在何处(ss:sp)而不知道栈空间大小
就像cpu只知道当前要执行嘚指令在何处(cs:ip),而不知道要执行的指令有多少
程序定义了栈段以后把ss:sp指向我们定义的栈端就可以了
push/pop 寄存器/段寄存器/[内存单元的偏移地址](段地址由ds指示)
1)IMUL r/m; ——————————————单操作数
lea是“load effective address”的缩写,简单的说lea指令可以用来将一个内存地址直接赋给目的操作数
在函数的反汇编中经常看到,debug版本:
上述指令相当于伪代码:
addl $1, %eax——源操作数在目标操作数的左边 |
格式:DOC ? 页数:23页 ? 上传日期: 22:15:46 ? 浏览次数:14 ? ? 1500积分 ? ? 用稻壳阅读器打开
全文阅读已结束如果下载本文需要使用
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。