8086汇编学习笔记12

模块化程序设计

系列文章

RET和RETF指令

RET指令(转移指令)
格式:
RET
用途:
该指令用栈中的数据,修改 IP 寄存器中的内容,从而实现近转移。

CPU执行RET指令时,进行下面两步操作:

  1. SS:SP 指向内存字单元中的数据修改 IP 寄存器
  2. SP 的值增加2

(换句话说,CPU执行 RET 指令时,相当于进行“ POP IP ”操作)

RETF指令(转移指令)
格式:
RET
用途:
该指令用栈中的数据,同时修改 CSIP 寄存器中的内容,从而实现远转移。

CPU执行 RETF 指令时,进行下面两步操作:

  1. SS:SP 指向内存字单元中的数据修改 IP 寄存器
  2. SP 的值增加2
  3. 再次用 SS:SP 指向内存字单元中的数据修改 CS 寄存器
  4. SP 的值增加2

(换句话说,CPU执行 RETF 指令时,相当于进行“ POP IP ”和“ POP CS ”操作)

CALL指令

CALL指令(转移指令)
格式:
CALL label
用途:
将当前的 IP 压栈后,转到标号处执行指令。

CPU进行 CALL 指令时,进行两步操作:

  1. 将当前的 IP ,或 CSIP 压入栈中
  2. 转移

(换句话说,CPU相当于执行“ PUSH IP ”和“ JMP near ptr label ”)

CALL 指令不能实现短转移,除此之外 CALL 指令实现转移的方式与和 JMP 指令相同。主要应用格式还有:

该格式实现的是段间转移,CPU执行此种格式的指令时,进行如下操作:

  1. SP 的值减少2
  2. SS:SP 指向内存字单元中的数据修改 CS 寄存器
  3. SP 的值减少2
  4. 再次用 SS:SP 指向内存字单元中的数据修改 IP 寄存器

(换句话说,CPU相当于执行“ PUSH CS ”、“ PUSH IP ”和“ JMP far ptr label ”操作)

将当前的 IP 压栈后,转到16位寄存器 16bit-reg 值代表的偏移地址处执行指令。

(换句话说,CPU相当于执行“ PUSH IP ”和“ JMP 16bit-reg ”)

将当前的 IP 压栈后,转到内存字单元的值代表的偏移地址处执行指令。

(换句话说,CPU相当于执行“ PUSH IP ”和“ JMP word ptr memory ”)

内存单元地址可用寻址方式的任意格式给出。

将当前的 CSIP 压栈后,转到内存双字单元的值代表的物理地址处执行指令。高地址处存放的字是物理地址的段地址,低地址处存放的字是物理地址的偏移地址。

(换句话说,CPU相当于执行“ PUSH CS ”、“ PUSH IP ”和“ JMP dword ptr memory ”)

内存单元地址可用寻址方式的任意格式给出。

CALL和RET的配合使用

CALLRET 指令经常配合使用,用来实现子程序的设计,即具有一定功能的程序段

在需要使用的时候,可以用 CALL 指令转去执行,此时 CALL 指令后面指令的地址将存储在栈中。
执行完子程序后,可以在子程序后面使用 RET 指令,用栈中的数据设置 IP 的值,从而转到 CALL 指令后面的代码处继续执行。

这样,可以利用 CALLRET 来实现子程序的设计。子程序的框架为:

label:
    ; ...code...
    RET

这样,具有子程序的源程序的框架为:

assume cs: codes
codes segment
main:
    ; ...code...
    CALL sub1
    ; ...code...
mov ax, 4c00h
int 21h
sub1:
    ; ...code...
    CALL sub2
    ; ...code...
    RET sub2:
    ; ...code...
    RET     ; ...code...
codes ends
end main

以下示例程序使用子程序的方式来计算阶乘:

assume cs: codes, ds: datas, ss: stacks
datas segment
datas ends
stacks segment
    db 128 dup (0)
stacks ends
codes segment
start:
    mov ax, stacks
    mov ss, ax
    mov sp, 128 ; set stack
    mov dx, 3
    mov cx, 6
    call pow
    mov ax, 4c00h
    int 21h
pow:
    add dx, dx
    loop pow
    ret
codes ends
end start

在寄存器 CX 中移入不同的值,即可计算不同次方的阶乘。

MUL指令

MUL指令(乘法指令)
格式:
MUL container
用途:
container 对应的寄存器或存储空间中的值作为乘数进行乘法运算。

两个相乘的数,要么都是8位,要么都是16位:

内存单元地址可用寻址方式的任意格式给出。

乘法运算的结果