7.1 and和or指令
(1)and指令:逻辑与,按位与运算
例如:
mov al,01100011B
and al,00111011B
执行后——al=00100011B
11为1,其余为0
(2)or指令:逻辑或,按位或运算
例如:
mov al,01100011B
or al,00111011B
执行后——al=01111011B
00为0,其余为1
在8086寄存器中,si和di寄存器的功能与bx相似,但是si和di是16位,不可分成高低8位的。
比如我们要把数据从原始内存转移到新内存,si通常放原始内存的地址,di通常放新内存的地址。
有部分寄存器可以用在中括号里面,有些不能。
在汇编语言中如何表达数据的位置?
我们用三个概念来表达数据的位置
- 立即数(idata)
- 寄存器
- 段地址(SA)和偏移地址(EA)
寻址方式的学习
寻址方式综合应用
div指令
为什么除数和被除数的位数要差2倍呢?
因为如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数。
9. 转移指令的原理
8086的转移指令分为以下几类
- 无条件转移指令 如jmp
- 条件转移指令
- 循环指令(loop)
- 过程
- 中断
这些转移的前提条件可能不同,但是基本原理相同。我们现在主要通过学习jmp来理解CPU的基本原理。
9.1 偏移操作符offset
比如
assume cs:codesg
codese segment
start: mov ax,offset start //相当于mov ax,0
s:mov ax,offset s //相当于mov ax,3
codesg ends
end start
offset操作符取得了标号start和s的偏移地址0和3,所以相当于后面的代码
9.2 jmp指令
jmp位无条件转移,可以只修改IP,也可以同时修改CS:IP
这就需要给出两种信息
- 转移的目的地址
- 转移的距离(段间转移,段内短转移,段内近转移)
9.3 依据位移进行转移的jmp指令
9.3.1 短转移jmp short ptr
这种指令实现的市段内短转移,他对IP的修改范围为-128~127,也就是说,他向钱转移可以最多越过128字节,向后最多越过127字节。转移指令结束后,CS:IP应该指向标号处的指令。
但是机器指令中不包含目的地址,意思就是说CPU不需要目的地址就可以实现对IP的修改。
以上两张图,第二张图比第一张图多了两个字节的代码,那个jmp的机器码就不一样了。
9.3.2 jmp near ptr标号
其实现的功能为:(IP)=(IP)+16
- 16位位移=标号处的地址-jmp指令后的第一个字节的地址
- near ptr指明此处是16位位移,进行的是段内近转移
- 16位位移的范围是-32768~32767,用补码表示。
- 16位位移由编译程序在编译时计算出
9.4 转移的目的地址在指令中的jmp指令
前面讲的jmp指令,其对应的机器码没有转移的目的地址,而是相对于当前IP的位移。
9.4.1 jmp far ptr指令
实现的是段间转移,又叫远转移。这里给出的不是偏移地址,而是目标地址。
9.5 转移地址在寄存器中的jmp指令
9.6 转移地址在内存中的jmp指令
示例: mov ax,0123h
mov ds:[0],ax
jmp word ptr ds:[0]
word ptr就是强制转化为字型数据
实验8
assume cs:codesg
codesg segment
mov ax,4c00h
int 21h
start: mov ax,0
s: nop
nop
mov di,offset s
mov si,offset s2
mov ax,cs:[si] ;就是把cs:[si]这个偏移地址内容的机器码给ax
mov cs:[di],ax
s0: jmp short s
s1: mov ax,0
int 21h
mov ax,0
s2: jmp short s1
nop
codesg ends
end start
可以看到在执行第15~16行代码时,就是把cs:[si]这个偏移地址中(也就是标号为s2这一行)的机器码给了ax
也可以看到此时AX=F6EB 这个EB是jmp的意思,F6(-10的补码)则是偏移地址。意思就是偏移地址-10,
此时jmp这段代码就到了箭头所指的那一行,他的意思也是偏移地址-10,所以直接减到了第一行,就开始执行下图画蓝色圈的代码了。
跳转的本质,还是偏移,所以这个跳转不是指哪儿打哪儿,而是在第一次跳转命令的时候就已经设置好这句指令该往哪儿偏移多少了。