汇编学习笔记(四)

2019-12-27  本文已影响0人  Jesse_996

call和ret指令

call和ret都是转移指令,都修改IP,或同时修改CS和IP。

ret和retf

执行ret指令时,cpu执行以下2部操作:

  1. ip=ss*10H+sp
  2. sp=sp+2

相当于pop ip

执行retf指令时,进行下面4部操作:

  1. ip=ss*10H+sp
  2. sp=sp+2
  3. cs=ss*10H+sp
  4. sp=sp+2

相当于pop ip ;pop cs

call指令

执行call指令时,进行2部操作:

  1. 将当前ip或cs和ip压栈
  2. 转移

call不能实现短转移,除此之外,call实现转移的方法和jmp相同:

push ip
jmp near ptr 标号
push cs
push ip
jmp far ptr 标号
push ip
jmp 16位寄存器
push ip
jmp word ptr 内存单元地址
push cs
push ip
jmp dword ptr 内存单元地址

mul指令

mul是乘法指令,要注意以下两点:

  1. 两个相乘的数:要么都是8位,要么都是16位。如果是8位,一个放在al,一个放在8位寄存器或内存字节单元中;若是16位,一个在ax,一个在16位寄存器中。
  2. 结果:如果是8位乘法,结果默认放在ax中;如果是16位,结果高位放在dx,低位放在ax。

解决除法溢出的方法:

X/N = int( H/N)65536 + [rem( H/N )65536 + L ] / N
X:被除数,N:除数,H:高16位,L:低16位,int:取商,rem:取余数

标志寄存器

ZF标志(zero flag)

flag第6位是ZF,零标志位。它记录执行相关指令后,其结果是否为0。为0则zf=1,否则zf=0。
注意:8086中,有些指令是影响flag的,比如:add、sub、mul、div、inc、or、and等,它们大多是运算指令(逻辑或算数运算);有一些则对flag没影响,如:mov,push,pop等,大多是传送指令。

PF标志(Parity flag)

flag第2位是PF,奇偶标志位。看执行结果的所有bit位中1的个数是否是偶数。是偶数则pf=1,否则pf=0。
可以理解成1偶标志位。

SF标志位(Sign Flag)

flag第7位是SF,符号标志位。记录相关指令执行后结果是否为负。如果为负,sf=1;否则sf=0
注意:sg是cpu默认将数据当成有符号运算结果的记录。如果我们将数据当做无符号时,sf时没有意义的,虽然相关指令可能影响了它的值。是不是有符号运算取决于我们。

CF标志位(Carry Flag)

flag第0位是CF标志位。一般情况下,在进行无符号数运算时,它记录了运算结果的最高有效位向更高位的进位值,或借位值。
inc和loop指令不影响cf

OF标志位(Overflow Flag)

flag第11位是OF,溢出标志位。记录了有符号运算的结果是否溢出。有溢出of=1,否则of=0;

注意和CF的区别:
cf是对符号数运算有意义的标志位
of是对符号数运算有意义的标志位

adc指令

adc是带进位加法指令,它利用了CF位上记录的进位值。(add +carry --> adc)如:
adc ax,bx实现的功能是ax=ax+bx+cf
cpu提供adc的目的,就是来进行加法的第二步运算的。

sbb指令

sbb是带借位减法指令(sub borrow),利用cf记录的借位值。
sbb ax,bx实现的功能是ax=ax-bx-cf
cpu提供dbb的目的,就是来进行减法的第二步运算的。

cmp指令

cmp是比较指令,相当于减法指令,只是不保留结果。cmp会对flag产生影响。如:
cmp ax,axax-ax运算,但并不在ax中保存,仅影响flag。
进行·cmp ax,bx·比较后,通过flag可以看出比较结果

注意:单纯的看sf的值不能判断结果的正负,因为可能会发生溢出。
而通过sf和of的值可以判断。

  1. sf=1,of=0:没发生溢出,实际结果负,则逻辑结果也为负
  2. sf=0,of=0:同上,逻辑结果非负
  3. sf=1,of=1:有溢出,则实际与逻辑相反,逻辑为正。
  4. sf=0,of=1:实际结果非负,又of=1,则结果非0,所以实际为正,逻辑结果为负。

条件转移指令

通常配合cmp,由cmp先进行比较,改变了flag中的值,条件转移指令根据flag中的值执行。
下面根据无符号数的比较进行转移的有:

指令 含义 条件
je 等于则转移 由 zf=1 则转移
jne 不等于则转移 zf=0
jb 低于则转移 cf=1
jnb 不低于则转移 cf=0
ja 高于则转移 cf=0 且 zf=0
jna 不高于则转移 cf=1 或 zf=1

DF标志和串传送指令

flag第10位是DF,方向寄存器。在串处理指令中,控制每次操作后si、di的增减

movsb指令

格式:movsb
相当于:

mov es:[di],byte ptr ds:[si];(8086不支持这样的命令,这里只是描述)
if df = 0:
  inc si
  inc di
elif df = 1:
  dec si
  dec di

movsw

类似上面,就是si,di 每次加或减2

movsbmovsw进行的是串传送的一个步骤,通常配合rep使用,如:
rep movsb,相当于:

s:movsb
  loop s

可见rep是根据cx的值,重复执行后面的串传送指令。

pushf和poopf

pushf功能是将标志寄存器的值压栈,popf是从栈中弹出数据给标志寄存器中。
通过pushf和popf,可以直接访问flag

上一篇 下一篇

猜你喜欢

热点阅读