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。
时间: 2024-11-15 06:22:18