计组11
CF:反映无符号数加减是否溢出
简单来说就是当加法的时候是否导致了高位进位产生一个1,减法进位产生一个0
OF:反映有符号数加减是否溢出,简单来说就是同符号是否产生不同符号
两个负的加出一个正的肯定是错了,两个正的加出来一个负的也肯定是错了
ZF:看是否是全零,对于有无符号都有意义
SF:符号位,仅对有符号加减法有意义
注意,不论有符号加减法还是无符号加减法都不代表这几个位不会产生变动,都可能的
无非是有时候没有意义而已罢了
参考此节进行学习,理论上还需要下功夫
其中cin为0的时候是加法,cin为1的时候是减法,无符号和有符号均适用
这里就直接谈核心重点了,这两个指令的作用就摆在这,后面会有更详细的介绍
这边只是粗略上给出了大致的操作内容
其实实际上是压入两个内容,一个是PC的返回地址,其实也可以称作是IC的返回地址
这两个是同一个东西,在取址后都会进行自增操作,然后X86里面都是按字节进行编址的
所以就要稍微注意下相对应的增量到底是多少,课后习题基本都有
另外一个东西就是上一段程序的起始地址,否则后续的EBP就无法返回正常位置
课后习题其实也声明过,如果是嵌套循环那么必须是压栈,如果是只有一层那么可以寄存
返回的话其实就是把返回地址给赋值返回给IC/PC,然后就能正常执行下一句父层指令
当然后面会有更详细的介绍,目前先写到这
在内存里面这个栈实际上是反着放的,另外就是需要说明这个栈是在内存里面放的
在X86里面默认一个栈块是32位,也就是4个字节,书上讲的其实很详细,例如存储浪费等
建议看书,这里只需要记住一个栈里面有多个帧栈,EBP/ESP指向的是当前执行程序的帧栈底和顶
所以相对应的加减其实也有变化,例如POP/PUSH操作也会有一定的变化
指针向下走是减法,向上走是加法
这里主要总结两种方法,至于入栈、出栈,其实指针指向不同也会有不同的操作
例如指针如果一开始指向的是空的,那么就是先入栈再减,或者先增加再出栈,具体来定
这里还需要声明的一点就是一般EBP是不变的,而ESP是经常改变的
一般的访问其实还有更多的方法,最主要的就是MOV指令,可以根据ESP、EBP两者
选择他们附近的块内容,例如EBP+8或者EBP+12、ESP+12等等,向上向下都行
一般初始化的时候,都会对ESP进行一次减法操作,用于初步给定一个栈的容量大小
当然也可以进行ESP加法操作来出栈或者删除一部分栈顶元素,完全是可灵活对待
至于指令,书上的能懂基本没问题,只要清楚几个比较特殊的点就行:
首先就是比较指令,是前者和后者相比
再就是四则运算指令,是前者四则运算后者
还有就是一般寄存器里面的内容是直接采取esp、ebp的读取法,没必要加括号
只有访问主存的时候需要加括号,读指令基本不会有问题
有兴趣可以根据这个图走一遍,不难的
下面就是对之前的CALL和RET进行进一步细化的过程,不排除考大题的读法
在读到CALL命令以后,会将当下的IC压栈(即主程序中的下一条执行指令,并无条件跳转
无条件跳转到新程序的第一条地址
此时因为压栈,所以ESP自动会进行加四的操作
然后就是跳转到新程序中执行语句,其中任意一个非Main程序起始必然是这样的几句
首先是把父程序的基地址给压入栈中,此时ESP所指内容即为父程序的基地址,同时自加
然后把让EBP指向和ESP同指向的区域
所以其实可以看出任意一个子程序(栈帧)的开头必然是其父程序的首地址
然后就是考虑返回的事情了
首先让新的帧栈清空,即让栈顶指向基地址
然后把基地址出栈,即为上一层的父帧栈的基地址,需要保持不能丢掉,现在返回给EBP
这样就能保证EBP重新指向父帧栈的正常基地址
出栈后,此时的EBP指向的也就是下一个IC执行地址,然后把IC值出栈恢复即可
至于其他的类似于赋值访问,我的建议是看PPT即可,这里就不再赘述
后面就是谈到了因为帧栈是以32位一块的,所以大概率是会产生一定的浪费情况在的
此外当需要使用上一层的寄存器的时候,需要先把相应的寄存器内容给放在栈里面
用完了再需要恢复
然后再谈这一节的复习方法和杂谈:
首先肯定是X86几个寄存器,这几个寄存器是一定要熟知能清楚是什么的,以及相关命令
好歹是要看懂英文到底表达的含义是什么
dword ptr\word ptr\byte ptr要清楚其含义
大部分指令书上讲的都很不错,没有必要拿PPT补充的
至于Intel格式,主要注意的就是其目的操作数和原操作数的顺序,计算、运算顺序
至于主存地址偏移量,用处就在于结构体可能是一块块的,所以才搞得比较复杂
这里是JMP的一些指令格式,看到要懂就行,以后会详细总结下,但无非就那么几种
至于选择指令,IF/ELSE结构,其中必然是会有一个无条件转移指令的
因为一段IF/ELSE结束后是一定要结束程序的,所以必然会有无条件跳转指令
至于运行的代码段,这个顺序肯定是可以随意变化的,课后习题已经详细说过,不赘述
对于循环结构,也肯定是需要有条件跳转指令,用来判断循环是否继续执行下去
如果不执行下去那么就一定要跳转
对于不同的循环、选择结构,其跳转指令的条数不一定相同,书上大致上是有写的,细化
至于LOOP指令,补充的LOOPNZ/LOOPZ都是对操作数的判断,看操作数是否为零结束循环
需要注意的就是LOOP是默认对ECX寄存器操作的,不能拿别的寄存器去存这个计数值在的
其他的,类似于机器级的阅读、执行顺序,其实更多可以参考这块方向
一般只会大致上考察一个阅读能力,知道中间执行的方法、内容基本就足够了