(二)常用指令简单介绍

2017-07-10  本文已影响0人  SwiftAlan

1、内存中字的存储

CPU 中,用 16 位寄存器来存储一个字,高 8 位放在高位字节,低 8 位放在低字节。比如我们从 0 地址开始存放 20000,如下图所示,在图中用 01 两个内存单元来存储 20000(4E20H)01 这两个单元可以看做一个起始地址为 0 的字单元,则数据 4E20H 的低位字节放在 0 号单元中,高位字节存放在 1 号单元中。

2、mov、add、sub 指令

mov 指令有以下几种形式

mov 寄存器,数据                  如:mov ax,6
mov 寄存器,寄存器                 如:mov ax,bx
mov 寄存器,内存单元               如:mov ax,[0]
mov 内存单元,寄存器               如:mov [0],ax
mov 段寄存器,寄存器               如:mov ds,ax
注:mov 内存单元,内存单元          如:mov [0],[1]   这是错误的写法,mov 指令不能用内存地址直接对内存地址赋值

3、栈

栈是一种具有特殊的访问方式的存储空间,遵循后进先出的规则。8086 CPUSS:SP 指示栈顶的位置,并提供 pushpop 指令实现压栈和出栈。
pushpop 指令有以下几种形式

push 寄存器     push ax         将寄存器 ax 的数据压入栈中
pop 寄存器      pop ax          从栈顶取出数据送入 ax
注:8086 CPU 的压栈和出栈操作都是以字节为单位进行的。

4、loop 指令

英文单词 loop 有循环的意义,显然这个指令和循环有关。
loop 指令格式:loop 标号CPU 执行 loop 指令的时候,要进行两部操作

1. sub cx,1H     先将 cx 减一
2. 判断 cx 中的值,不为零则跳转至标号处执行程序,为零则向下执行。
例:add ax,ax 需要重复执行 10 次
mov cx,10
s:  add ax,ax
loop s

5、mul、div 指令

mul 乘法指令
(1)两个相乘的数要么都是 8 位,要么都是 16 位;如果是 8 位,一个存放在 al 中,另一个存放在 8 位的寄存器或者内存字节单元中;如果是 16 位,一个默认值 ax 中,另一个放在 16 位寄存器或内存单元字中。
(2)结果:如果是 8 位乘法,结果默认放在 ax 中;如果是 16 位乘法,结果高位默认在 dx 中,地位在 ax 中。

指令格式:mul 寄存器      如:mul ax
mul 内存单元     如:mul byte ptr ds:[0]

div 除法指令
(1)除数:有 8 位和 16 位两种,在一个寄存器或内存单元中;
(2)被除数:默认放在 axdxax 中,如果除数为 8 位,则被除数为 16 位,默认存放在 ax 中,如果除数为 16 位,被除数则为 32 位, dx 存放高 16 位, ax 存放低 16 位。
(3)结果:如果除数为 8 位,则 al 存储除法操作的商, ah 存储除法操作的余数,如果除数为 16 位,则 ax 存储除法操作的商, dx 存储除法操作的余数。

指令格式:div 寄存器      如:div ax
div 内存单元     如:div word ptr ds:[0]

6、伪指令db、dw、dd、dup

db = define byte  定义数据宽度为一个字节
dw = define word  定义数据宽度为一个字
dd = define duble word  定义数据宽度为两个字

dup 是一个操作符,它是配合 db dw dd 等数据伪指令一起使用的,用来数据的重复。

指令格式:db 重复次数 dup(重复的字节型数据)
指令格式:dw 重复次数 dup(重复的字型数据)
指令格式:dd 重复次数 dup(重复的双字型数据)
db 3 dup(0,1,2)
定义了 `9` 个字节,相当于 `db 0,1,2,0,1,2,0,1,2`

7、offset 操作符

操作符 offset 在汇编语言中是由编译器处理的符号,它的功能就是取得标号的偏移地址,比如下面的程序

assume cs:code
codesg segment
start: mov ax,offset start      ;相当于 mov ax,0
s: mov ax,offset s      ;相当于 mov ax,3
codesg ends
end start

在上面的程序中,offset 操作符取得了标号 starts 的偏移地址 03,因为第一条指令的长度为 3 个字节,则 s 的偏移地址为 3

8、转移指令

可以修改 IP 或者同时修改 CSIP 的指令统称为转移指令,概括的讲,转移指令就是可以控制 CPU 执行内存中某处代码的指令。

8086 CPU 的转移行为有以下几类
* 只修改 IP 时,称为段内转移,比如:jmp ax
* 同时修改 CS 和 IP 时,称为段间转移,比如:jmp 1000:10
由于转移指令对 IP 的修改范围不同,段内转移又分为以下两种情况
* 短转移 IP 的修改范围为 -128~127
* 近转移 IP 的修改范围为 -32768~32767
8086 CPU 的转移指令有以下几类
* 无条件转移指令,如:jmp
* 条件转移指令,如:jz
* 过程
* 中断

jmp 指令格式

jmp short 标号     实现段内短转移
jmp near ptr 标号  实现段内近转移
jmp far ptr 标号   实现段间转移,又称为远转移
jmp word ptr 内存单元地址(段内转移)
jmp dword ptr 内存单元地址(段间转移)
功能:从内存单元地址处放着两个字,高地址处的字是转移的目的段地址,低地址处是转移目的偏移地址。

8、call 和 ret 指令

ret 指令用栈中的数据,修改 IP 的内容,从而实现近转移;
retf 指令用栈中的数据,修改 CSIP 的内容,从而实现远转移;

CPU 执行 ret 指令时,进行下面 2 步操作
1、(IP) = ((ss)* 16 + (sp))
2、(sp) = (sp) + 2   相当于 pop ip
CPU 执行 retf 指令时,进行下面 4 步操作
1、(IP) = ((ss)* 16 + (sp))
2、(sp) = (sp) + 2   相当于 pop ip
3、(CS) = ((ss)* 16 + (sp))
4、(sp) = (sp) + 2   相当于 pop cs

call 不能实现短转移,除此之外,call 指令实现转移的方法和 jmp 指令的原理相同,主要进行两个步骤

1、将当前的 `IP` 或 `CS` 和 `IP` 压入栈中
2、转移
上一篇 下一篇

猜你喜欢

热点阅读