loop指令

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

    loopx lab

  • loop
    循环直到ecx为0。
    一个错误的例子:
 1 .section .data
 2 output:
 3     .asciz "array[%d]:%d\n"
 4 array:
 5     .int 1,2,3,4,5,6,7,8,9,10
 6 .section .text
 7 .globl main
 8 main:
 9     nop
10 /**
11 ** 一个错误的例子,ecx在printf中被重写
12 **/    
13 /*    movl $9, %ecx
14 Loop1:
15     #pushal
16     pushl array(,%ecx,4)
17     pushl %ecx
18     pushl $output
19     call printf
20     addl $12, %esp
21     #popal
22     loopne Loop1
23 */    
24     pushl $0
25     call exit

 

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

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

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

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

 1 .section .data
 2 output:
 3     .asciz "sum:%d\n"    
 4 
 5 .section .text
 6 .globl main
 7 main:
 8     nop
 9 /*清掉EFLAGS中的ZF*/
10     movl $1, %eax
11     addl $2, %eax
12     
13     movl $0, %ecx
14     movl $0, %eax
15 loop1:    
16     addl %ecx, %eax
17     loop loop1
18     #loopne loop1
19     pushl %eax
20     pushl $output
21     call printf
22     addl $8, %esp
23     
24     pushl $0
25     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。

posted @ 2015-03-11 13:50  thammer  阅读(3146)  评论(0编辑  收藏  举报