当然有LOOP的功能啊!
当int 7cH中断运行后,处理器先压栈2个字节的标志寄存器,再压栈2个字节段寄存器,再压栈2个字节的IP值。
然后进入第一行,标号LP处,
lp:push bp ;将寄存器bp压栈保存,因为下面的过程会要用到,以免破坏数据,先压栈保护。
mov bp,sp ;此时的SP指向栈顶,将指向栈顶的SP传送给寄存器BP,那么BP也指向栈顶。
dec cx ;loop指令首先是将寄存器CX自减1,这里也是模拟该功能,将CX自减1。
jcxz lpret ;如果CX等于0,则跳转到标号lpret处,该处直接从栈中弹出第1行压入的BP值,恢复它。
add [bp+2],bx ;如果cx不等于0,则执行此处。
;从第2行我们可以看到BP=SP的值,所以SS:BP也是指向栈顶的。
;我们知道栈是向下扩展的,也就是说每压入一个数据,栈顶指针数据变小。
;BP指向栈顶,而最后的压入的那个数据是哪个?是标号lp处压入的BP值。
;那么BP+2指向的就是压入的IP值,它是倒数第2个压入的数据。
;BP+2指向的IP值在中断进入之前压入的就是标号se的值。
;将标号se的值加上偏移量BX,则其值会指向标号S处。
;将指向标号S处的值传送给BP+2处。
lpret:pop bp ;从栈中弹出一个字给寄存器BP,之后,栈顶指针指向压入的IP值处。
iret ;iret的功能就是先弹出一个字给IP寄存器,再弹出一个字给CS寄存器
;再弹出一个字给标志寄存器,这是按中断执行时的压入顺序反向弹出。
如果cx寄存器的值为零,对于loop指令来数,循环结束了,执行下一条指令,即标号se处。而对于7cH中断来说,如果CX寄存器的值为零,则add [bp+2],bx这一步不会执行,因此IP的值也就不会被修改到标号S处,iret弹出CS和IP后,CS:IP直接指向下一条指令,即标号se处。如果CX寄存器的值不为零,则会执行add [bp+2],bx这一步,那么,IP的值会被修改为标号S处的值,iret后,CS:IP就会指向标号S处,从那里开始执行。这样不就实现了LOOP的功能吗?