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

六、整数算术指令

Untitled

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

Untitled

Untitled

分为四组

  1. SHL SHR
  2. SAL SAR
  3. ROL ROR
  4. RCL RCR
  5. 【SHLD SHRD】

Untitled

Untitled

Untitled

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

Untitled

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

Untitled

Untitled

Untitled

Untitled

Untitled

Untitled

应用:

Untitled

Untitled

Untitled

乘法和除法指令

MUL指令:无符号乘法

Untitled

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

Untitled

mul后面不能直接跟立即数

IMUL指令:有符号数乘法

Untitled

OF的意思是“是否溢出”、“去掉高位后结果是否仍正确”

  1. 由于结果的绝对值为C0h,高位表示符号位,所以结果不能只用八位表示,所以OF=1
  2. 由于结果的绝对值连同符号位,用8位可以装下,高位单纯是符号位的扩展,所以OF=0
  3. 同上

Untitled

Untitled

Untitled

Untitled

Untitled

Untitled

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

Untitled

Untitled

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

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

Untitled

由于var3是32bit,所以需要把var2拓展到64位

(-5 * var1)得到的结果就是64位,直接哪来出32位的ebx,上放在32位的eax中,nice

拓展加法和减法

Untitled

Untitled

Untitled

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

Untitled

Untitled

七、高级过程

堆栈参数

Untitled

Untitled

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

Untitled

Untitled

堆栈框架

Untitled

Call AddTwo 又等价为

push IP;
mov ip,OFFSET AddTwo; ;【只是表意,实际上不能直接给ip赋值】

ret 8 表示ret后再把SP+8,也就是再弹出两个栈中元素【一个栈元素4字节(32位程序)】

pop IP;
add SP,8;

这两个栈元素就是之前压入的两个参数

Untitled

堆栈传递函数参数

Untitled

入栈:

  1. push 6 push 5 将参数压入堆栈
  2. call AddTwo 将返回地址压入堆栈
  3. push ebp 将“主程序的基址指针寄存器”压入堆栈,防止覆写,因为后面要用到它来进行参数寻址

寻址:

出栈:

  1. pop ebp 把ebp出栈
  2. ret 8 把ip【返回地址】出栈;把esp+8,把两个参数从栈中清空

堆栈存储局部变量

首先明白一点:全局变量存储在内存中,局部变量存储在内存的堆栈中

字节是寻址的最小单元,内存中数据按字组织对齐

字节是寻址的最小单元,内存中数据按字组织对齐

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

Untitled

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

实际反汇编结果

Untitled

处理局部变量的代码插入20与21行之间

ArrayPad用来检查数组是否越界

程序开始执行时: ArrayPad = ebp XOR 随机数

程序要返回时:ecx = ArrayPad XOR ebp call 调用的函数会检查 ecx == ebp ,显然如果一切正常,必然相等,但是如果数组越界了,就会把ArrayPad覆盖掉,导致 ecx和ebp不相等,编译器这就完成了对数组越界的简单检查

递归:略

创建多模块程序:略

posted @ 2025-09-15 17:04  Miaops  阅读(13)  评论(0)    收藏  举报