用 MUL 指令做乘法
格式
- MUL 寄存器
- MUL 寄存单元
8 位乘法 | 16 位乘法 | |
---|---|---|
被乘数(默认) | AL | AX |
乘数 | 8 位寄存器或内存单元 | 16 位寄存器或内存字单元 |
结果 | AX | DX (高位) 和 AX (低位) |
模块化程序设计
- 调用子程序 : CALL 指令
- 返回 : RET 指令
实质
流程转移指令,它们都修改 IP ,或同时修改 CS 和 IP
CALL 指令
字面意思
调用子程序
实质
- 流程转移
- CALL 指令实现转移的方法和 JMP 指令的原理相似
格式
CALL 标号
- 16 位位移 = “标号”处的地址 - CALL 指令后的第一个字节的地址
- 16 位位移的范围为 \([-32768,32767]\) ,用补码表示
- 16 位位移由编译程序在编译时算出。
CPU 执行 CALL 指令的流程
- 将当前 IP 或 CS 和 IP 压入栈中
- 转移到标号处执行指令
CPU 执行 CALL 指令的原理
- (SP) = (SP) - 2 ((SS) * 16 + (SP)) = (IP)
- (IP) = (IP) + 16 位位移
相当于PUSH IP
再JMP NEAR PTR 标号
CALL FAR PTR 标号
实现的是段间转移
CPU 执行 CALL FAR PTR 标号
时的操作
(SP) = (SP) - 2
((SS) * 16 + (SP)) = (CS)
(SP) = (SP) - 2
((SS) * 16 + (SP)) = (IP)
- (CS) = 标号所在的段地址 (IP) = 标号所在的偏移地址
CALL FAR PTR 标号
相当于
PUSH CS
PUSH IP
JMP FAR PTR 标号
转移地址在寄存器中的 CALL 指令
指令格式
CALL 16位寄存器
功能
(SP) = (SP) - 2
((SS)*16+(SP)) = (IP)
(IP) = (16位寄存器)
相当于进行
PUSH IP
JMP 16位寄存器
转移地址在内存中的 CALL 指令
- CALL WORD PTR 内存单元地址
相当于 :PUSH IP
和JMP WORD PTR 内存单元地址
- CALL DWORD PTR 内存单元地址
相当于 :PUSH CS
、PUSH IP
和JMP DWORD PTR 内存单元地址
返回指令 RET 和 RETF
RET 指令 | RETF 指令 | |
---|---|---|
功能 | 用栈中的数据,修改 IP 的内容,从而实现近转移 | 用栈中的数据,修改 CS 和 IP 的内容,从而实现远转移 |
相当于 | POP IP | POP IP POP CS |
RET (字面值 n)
含义
POP IP
ADD SP,N
为 CALL 和 RET 指令设置栈
不定义栈段区时使用 CALL 和 RET 指令,使用的未经定义与分配的内存空间作为栈,代码很危险,所以一定要提前定义声明栈段区
子程序
根据提供的参数处理一定的事务,处理后,将结果(返回值) 提供给调用者。
用寄存器来存储参数和结果是最常使用的方法
适用于参数和返回值不多的情况下
用内存单元批量传递数据
- 将批量数据放到内存中,然后将它们所在内存空间的首地址放在寄存器中,传递给需要的子程序
- 对于具有批量数据的返回结果,也可用同样的方法
用栈批量传递参数
- 由调用者将需要传递给子程序的参数压入栈中,子程序从栈中去的参数