loop系列的指令有:loop,loope/loopz,loopne/loopnz,它们都是借助于ECX寄存器作为计数来实现循环,每轮循环先ecx自动减1,再来判断ecx值,ecx的自减不会影响OF和CF。通用的格式是

    loopx lab

  • loop
    循环直到ecx为0。
    一个错误的例子:
 .section .data
output:
.asciz "array[%d]:%d\n"
array:
.int ,,,,,,,,,
.section .text
.globl main
main:
nop
/**
** 一个错误的例子,ecx在printf中被重写
**/
/* movl $, %ecx
Loop1:
#pushal
pushl array(,%ecx,)
pushl %ecx
pushl $output
call printf
addl $, %esp
#popal
loopne Loop1
*/
pushl $
call exit

  在loop循环中调用其他函数极易重写ecx的值,这样一来循环被破坏,这点要特别注意。

  • loope/loopz

    • 循环直到ecx不为0,2个指令无任何区别
  • loopne/loopnz
    • 循环直到ecx为0,2个指令无任何区别

  这样看来,loop ,loopne/loopnz这3个指令好像都是一回事,先看下面的代码:

  这段代码是一个简单的求和代码

 .section .data
output:
.asciz "sum:%d\n" .section .text
.globl main
main:
nop
/*清掉EFLAGS中的ZF*/
movl $, %eax
addl $, %eax movl $, %ecx
movl $, %eax
loop1:
addl %ecx, %eax
loop loop1
#loopne loop1
pushl %eax
pushl $output
call printf
addl $, %esp pushl $
call exit

  如果采用17行loop作为循环条件,ecx自减1,为-1,不为0,那么继续循环,也就是从0xFFFFFFFF---->0x0,结果是:

    sum:-2147483648

  如果采用18行loopne,结果是:

    sum:0

  细看loop:Loop until the ECX register is zero
  loopne/loopnz:Loop until either the ECX register is zero, or the ZF flag is set
  loopne/loopnz 多了一个条件,ZF也影响其判断。代码中虽然ecx在执行18行时,先ecx自减,为-1,但是同时16行代码导致ZF被置位,所以依旧执行了跳转。

  loope/loopz也判断了ZF。

05-03 20:54