西电微机原理-第三章 Intel处理器指令系统及汇编语言(3)
六、整数算术指令

移位和循环移位指令及其应用


分为四组
- SHL SHR
- SAL SAR
- ROL ROR
- RCL RCR
- 【SHLD SHRD】



SHL和SHR分别用作 无符号数 的快速乘除法

SAR用作 有符号数 的快速除法






应用:



乘法和除法指令
MUL指令:无符号乘法

因为是无符号数,所以溢出判断是用CF

mul后面不能直接跟立即数
IMUL指令:有符号数乘法

OF的意思是“是否溢出”、“去掉高位后结果是否仍正确”
- 由于结果的绝对值为C0h,高位表示符号位,所以结果不能只用八位表示,所以OF=1
- 由于结果的绝对值连同符号位,用8位可以装下,高位单纯是符号位的扩展,所以OF=0
- 同上






cb和cwd作用是拓展被除数,保证是除数的两倍


如果CF=0,说明没有进位,乘积的高32位可以去掉
如果CF=1,说明进位了,乘积的高32位不是全0,不可以去掉

由于var3是32bit,所以需要把var2拓展到64位
(-5 * var1)得到的结果就是64位,直接哪来出32位的ebx,上放在32位的eax中,nice
拓展加法和减法



- 由于下面要用到32位寄存器,所以要入栈保存原数据 pushad
mov eax,[esi]和adc eax,[edi]计算了32位加法,进位保存在CF,在下次循环参与运算- 由于下面有
add会影响进位标志位,所以需要保存PSW,pushsf


七、高级过程
堆栈参数


- 寄存器参数:主程序通过寄存器传递参数【参数少时可用】
- 堆栈参数:主程序通过堆栈传递参数【常用】
- 用 PROTO和INVOKE定义和调用函数


堆栈框架

Call AddTwo 又等价为
push IP;
mov ip,OFFSET AddTwo; ;【只是表意,实际上不能直接给ip赋值】
ret 8 表示ret后再把SP+8,也就是再弹出两个栈中元素【一个栈元素4字节(32位程序)】
pop IP;
add SP,8;
这两个栈元素就是之前压入的两个参数

堆栈传递函数参数

入栈:
push 6push 5将参数压入堆栈call AddTwo将返回地址压入堆栈push ebp将“主程序的基址指针寄存器”压入堆栈,防止覆写,因为后面要用到它来进行参数寻址
寻址:
出栈:
pop ebp把ebp出栈ret 8把ip【返回地址】出栈;把esp+8,把两个参数从栈中清空
堆栈存储局部变量
首先明白一点:全局变量存储在内存中,局部变量存储在内存的堆栈中

字节是寻址的最小单元,内存中数据按字组织对齐
为什么 char 占用4个字节:因为内存中的数据为了方便寻址,需要进行地址对齐,对齐的倍数为字的大小,32位系统为4个字,所以地址必须是4的整数倍,所以需要对齐到4

IEE754写法
32位
- 1+8+23
- 8:(规格化后的指数+0111 1111)
64位
- 1+11+52
- 11:(规格化后的指数+0 111 111 111 1)
例子:
\(*1.2d = 1.0011 0011 0011 ... * 2^0*\)
IEE754:
0 (011 1111 1111) 0011 0011 0011 … = 3ff 3333…h
实际反汇编结果

处理局部变量的代码插入20与21行之间
ArrayPad用来检查数组是否越界
程序开始执行时: ArrayPad = ebp XOR 随机数
程序要返回时:ecx = ArrayPad XOR ebp call 调用的函数会检查 ecx == ebp ,显然如果一切正常,必然相等,但是如果数组越界了,就会把ArrayPad覆盖掉,导致 ecx和ebp不相等,编译器这就完成了对数组越界的简单检查

浙公网安备 33010602011771号