基本概念
[...]
表示一个内存单元
mov ax, [0]
操作单位是字
mov al, [0]
操作单位是字节()
为了学习的方便表示一个内存单元或寄存器中的内容
(ax) = 0010H
mov ax, [2]
描述为(ax)=((ds) * 16 + 2)
idata
表示常量
mov ax,[idata]
代表mov ax, [1]
mov ax,[2]
…- 在汇编源程序中,数据不能以字母开头,要在
ffff
前面加0
mov ax, 0ffffh
- 字节型数据的范围为 0~255
字型数据的范围为 0 ~ 65535 - 要处理的数据有多长
mov
- mov 寄存器, 数据
- mov 寄存器, 寄存器
- mov 寄存器, 内存单元
- mov 寄存器, 段寄存器
- mov 内存单元, 寄存器
- mov 内存单元, 段寄存器
- mov 段寄存器, 寄存器
- mov 段寄存器, 内存单元
- 用mov指令要访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在
DS
寄存器中
add 指令
- add 寄存器, 数据
- add 寄存器, 寄存器
- add 寄存器, 内存单元
- add 内存单元, 寄存器
sub 指令
- sub 寄存器, 数据
- sub 寄存器, 寄存器
- sub 寄存器, 内存单元
- sub 内存单元, 寄存器
adc指令
- 带进位加法指令
- 意思就是不论add还是adc,都会将进位保存在CF中,只是add相加的时候不会加上CF中的进位,而adc会加上CF中的进位
- 可以用于大数相加
- 128位数据的相加
通过sub ax
,ax将CF清0
add di,2
,是会影响标记位的
sbb指令
cmp指令
- cmp是比较指令,功能相当于减法指令,只是不保存结果
- cmp指令执行后,将对标志寄存器产生影响,可以用标志寄存器的值,确定比较结果
- 进行有符号数的比较
- 条件转移指令
jxxx
系列指令和cmp指令配合实现if语句的功能cmp ah,bh je s add ah,bh jmp short ok s: add ah,ah ok:ret
- 统计数值为8的字节的个数
;解法1 data segment db 8,11,8,5,63,38 data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov ax,0 mov cx,0 s: cmp byte ptr [bx], 8 je ok jmp short next ok: inc bx next: inc bx loop s mov ax,4c00h int 21h code ends ;解法2 code segment start: mov ax,data mov ds,ax mov bx,0 mov ax,0 mov cx,8 s: cmp byte ptr [bx],8 jne next inc ax next inc bx loop s mov ax,4c00h int 21h code ends
jmp指令
- CS和IP不能通过mov指令来修改,8086CPU不提供对CS和IP修改的指令
jmp 段地址:偏移地址
同时修改CS、IP的内容jmp 某一合法寄存器
仅修改IP的内容
div指令
- a÷b=q,a称为被除数,b称为除数
- 被除数:(默认)放在AX或DX和AX中
除数:8位或16位,在寄存器或内存单元中
- div指令格式
div 寄存器
/div 内存单元
- 例:用除法指令计算
100001 / 100
mov dx,1 mov ax,86A1 mov bx,64 div bx
- 例:用除法指令计算
1001 / 100
mov ax,3E9 mov bl,64 div bl
- 在内存单元中实施除法
mul指令
dup指令
- dup和db、dw、dd等数据定义伪指令配合使用,用来进行数据的重复
- 示例:
- dup的使用格式
movsb
- 以字节为单位传送
- 在串处理指令中,控制每次操作后si,di的增减
- DF = 0:每次操作后si、di递增
cld指令:将标志寄存器的DF位设为0(clear)
(si) = (si) + 1
(di) = (di) + 1 - DF = 1:每次操作后si、di递减
std指令:将标志寄存器的DF位设为1
(si) = (si) - 1
(di) = (di) - 1
movsw
- 以字为单位传送
- DF = 0:每次操作后si、di递增
(si) = (si) + 2
(di) = (di) + 2 - DF = 1:每次操作后si、di递减
(si) = (si) - 2
(di) = (di) - 2
rep指令
- 下面的这两个是等价的
有关栈的指令
8086CPU
支持用栈的方式访问内存空间- 基于
8086CPU
的编程,可以将一段内存当作栈来使用 push ax
; 将ax中的数据送入栈中
pop ax
; 从栈顶取出数据送入ax
8086CPU
中,有两个与栈相关的寄存器
栈段寄存器SS
—— 存放栈顶的段地址
栈顶指针寄存器SP
—— 存放栈顶的偏移地址
任意时刻,SS:SP
指向栈顶元素
执行push和pop指令时,SP中的内容自动改变
- push指令和pop指令的执行过程
push ax
——SP = SP - 2
pop ax
——SP = SP + 2
- 当栈满的时候再使用push指令入栈,将发生栈顶超界问题(栈顶超界是危险的)
同理,执行出栈(pop)时,栈顶也会超出栈空间
- 8086CPU不保证对栈的操作不会超界
8086CPU只知道栈顶在何处,不知道程序安排的栈空间有多大
所以只能自己小心
Loop指令
loop 标号
assume cs:code code segment mov ax, 2 // 在cs中设置循环次数 mov cs, 11 s: add ax, ax loop s mov ax, 4c00h int 21h code ends end
- 执行loop指令时要进行的操作
(cx) = (cx) - 1
判断cx中的值:不为零则转至标号处执行程序,如果为零则向下执行 - 例:计算ffff:0 ~ ffff:b 单元中的数据的和,结果储存在dx中
assume cs:code code segment mov ax,0ffffh mov ds,ax mov bx,0 mov dx,0 mov cx,12 s: mov al,[bx] mov ah,0 add dx,ax inc bx loop s mov ax,4c00h int 21h code ends end