cmp 指令

功能相当于减法指令 只是不保存结果
不过cmp执行后会影响标志位 其它指令 通过识别标志位 来得知比较的结果

CPU在执行cmp指令时 像add sub指令一样 也包含两种含义 (有符号 无符号)

 

无符号的 cmp

指令 cmp ax,bx 执行后

即(ax - bx 执行)

1  zf=1        ax   等于    bx 结果为0
2  zf=0        ax  不等于   bx 结果不为0

3  cf=1        ax  小于     bx 有借位
4  cf=0        ax 大于等于  bx 木有借位

5  cf=0且zf=0  ax   大于    bx 木有借位 并且结果不为0
6  cf=1或zf=1  ax 小于等于  bx 有借位则小  结果为0则等

 

有符号的 cmp

我们必须在查看sf(得知实际结果的正负)的同时还要查看of(得知有木有溢出)
就可以得知逻辑上真正结果的正负了 同时也可以知道比较的结果

指令 cmp ah,bh 执行后

即(ah - bh 执行)

相等不相等  直接看zf 与无符号的运算一样。。

1  sf=1 of=0 木有溢出 结果为负 实际结果=逻辑真正结果  所以 ah<bh
2  sf=1 of=1 有溢出 溢出导致实际结果为负 则逻辑真正结果必然为正  ah>bh
3  sf=0 of=1 有溢出 溢出导致实际结果为正 则逻辑真正结果必然为负  ah<bh
4  sf=0 of=0 木有溢出 结果为正 实际结果=逻辑真正结果  所以 ah>bh

 

jmp指令

无条件转移的指令 可以值修改ip 也可以同时修改 cs 和ip

 

jmp 指令一般要给出两点信息
1 转移的目的地址
2 转移的距离(段间转移  段内短转移  段内近转移)
  根据位移转移的时候 如果越界了 汇编编译器会报错
  位移转移的意义: 方便程序段在内存中的浮动装配

1 根据位移进行转移的jmp指令
  jmp short 标号(转到标号处执行指令)
  实现的是 :段内短转移 ip修改范围(-128-127)
  功能: 实现 ip=ip+8位位移(标号处-jmp指令后的第一个字节的地址)
  注释 short 就是说 8位位移
  jmp near 标号(段内近转移) 与 段内短转移 原理一样
  不过是 16 位位移  ip=ip+16位位移

2 转移目的地址在标号中的jmp指令
  jmp far ptr 标号  :实现的是 段间远转移
  功能: cs=标号所在的段的段地址
 ip=标号在段中的偏移地址

3 转移地址在寄存器中的jmp指令
  jmp 16位reg
  功能 ip=(16位reg)  汇编解释:mov ip,寄存器中的值

 而jmp word ptr [bx]是 跳到 (将bx的中值作为偏移地址) 的地方

4 转移地址在内存中的jmp指令   (有两种格式)
  1 jmp word ptr 内存单元地址(段内转移)
    功能 : 内存单元中存放着一个字 是转移的目的偏移地址
    内存单元地址 可以是 任意一种寻址方式给出
  2 jmp dword ptr 内存单元地址(段间转移)
    功能 从内存单元中开始存放着两个字 
  高地址[bx+2]的字是 目的 cs
  低地址[bx]  的字是 目的 ip

5 所有的条件转移指令都是短转移 (jmp信息是 位移,不是目的地址)
   (jcxz,je,jne,ja,jna,jb,jnb等等)
   jcxz 标号
   相当于 if((cx)==0)  jmp short 标号;
   je,jne,ja,jna,jb,jnb 是根据flag寄存器的某些标志位进行判断的
   紧挨他们前边的指令不一定去影响标志位
   他们只根据当前的 标志位 去判断
   cmp ax,bx
   je  标号      ;相不相等 判断zf

6 所有的循环指令都是短转移(jmp信息是 位移,不是目的地址)
  loop 标号
  loop指令实现
  解释  (cx)--
 if((cx)!=0)  jmp short 标号;

 

 

call ret 都是转移指令

都是修改ip 或 同时修改cs和ip

ret 指令 用栈中的数据 修改  ip  的内容 实现近转移
         相当于 pop ip
retf指令 用栈中的数据 修改cs和ip的内容 实现远转移
  相当于 pop ip  pop cs

ret;可能是近返回,也可能是远返回


retn ;近返回指令

在近类型的子程序中,返回指令RET是近返回,其功能是把栈顶之值弹出到指令指针寄存器IP中,SP会被加2

 

retf ;远返回指令

在远类型的子程序中,返回指令RET是远返回,其功能是:先弹出栈顶之值到IP中,再弹出栈顶之值到CS之中,SP总共会被加4


ret 6;子程序返回后,(SP)←(SP) + 6

如果返回指令后面带有立即数(其值通常为偶数),则表示在得到返回地址之后,SP还要增加的偏移量,它不是类似于高级语言中子程序的返回值

call指令 (不能实现短转移 其他转移和jmp指令是一样的)

cpu在执行call时 进行两步操作
1  将当前ip和cs压入栈中
2  转移

call指令的几种形式 (详见jmp指令)

1 call 标号
相当于
 push ip
 jmp near ptr标号
2 call far ptr 标号
相当于
 push cs
 push ip
 jmp far ptr 标号
3 call 16位寄存器
相当于
 push ip 
 jmp 16位寄存器
4 call word ptr 内存单元地址
相当于  
 push ip
 jmp word ptr 内存单元地址
5 call dword ptr 内存单元地址
相当于  
 push cs
 push ip
 jmp dword ptr 内存单元地址


call 与 ret 实现子程序的机制

子程序的框架

assume cs:code
code segment

main:
 :
 call sub1   ;调用子程序sub1
 :
 :
 mov ax,4c00h
 int 21h

sub1:
 :     ;子程序sub1的开始
 :
 call sub2   ;调用子程序sub2
 :
 :
 ret     ;子程序返回
 
sub2:
 :     ;子程序sub2的开始
 :
 ret     ;子程序返回
code ends
end main

 未完待续。。。