重复指令是一组操作数据缓冲区的指令。数据缓冲区通常是一个字节数组的形式,也可以是单字或者双字。(Intel‘称这些指令为字符串指令)
最常见的数据缓冲区操作指令是movsx、cmps、stosx和scasx,其中x可以是b、w后者d,分别表示字节、字和双字。这些指令对任何形式的数据都有效。
在这些操作中,使用ESI和EDI寄存器。ESI是源索引寄存器,EDI是目的索引寄存器。还有ECX用作计数的变量。
这些指令还需要一个前缀,用于对长度超过1的数据做操作。movsb指令本身只会移动一个字节,而不使用ECX寄存器。
在x86下,使用重复前缀来做多字节操作。rep指令会增加ESI和EDI这两个偏移,减少ECX寄存器。rep前缀会不断重复,直至ECX=0。repe/repz和repne/repnz前缀则不断重复,直至ECX=0或直至ZF=1或0。在大部分的数据缓冲区操作指令中,ESI、EDI和ECX必须为rep指令的生效而进行适当的初始化。
mvosb指令用于将一串字节从一个位置移动到另一个位置。rep前缀经常与movsb一起使用,从而赋值一串长度由ECX决定的字节。从逻辑上说,rep movsb指令等价于C语言的memcpy函数。movsb指令从ESI指向地址取出一个字节,将其存入EDI指向地址,然后根据方向标志(DF)的设置,将ESI和EDI的值加1或者减1。若果DF=0,则加,否则减。
cmpsb指令用于比较两串字节,以确定其是否是相同的数据。它经常与repe前缀一起使用,此时,cmpsb指令逐一比较两串字节,直至发现一处不同或比较到头。ECX=0或者ZF=0,就停止重复。相当于C语言中memcp函数。
scasb指令用于从一串字节中搜索一个值。这个值有AL寄存器给出。它的工作方式与cmpsb一样,但是它是将ESI指向地址的字节与AL进行比较,而不是与EDI指向地址的字节比较。repe操作会使得这个比较不断继续,知道找到该字节,或者ECX=0。如果在这串字节中找到了那个值,其位置会被存储在ESI中。
stosb指令用于将值存储到EDI指向的地址。它与scasb一样,但不是去搜索,而是将指定的字节存入EDI指向的地址。rep前缀与scasb一起使用后,就初始化了一段内存缓冲区,其中的每个字节都是相同的值。这等价于C语言的memset函数。
rep指令实例:
repe cmpsb 用于比较两块数据缓冲区。EDI和ESI必须被设为两端缓冲区的地址,ECX必须被设为缓冲区长度。当ECX=0或者发现缓冲区不一致的时候,停止比较。
rep stosb 用于用一个给定的值初始化一块缓冲区所有字节。EDI包含了缓冲区地址,AL则包含初始值。这个指令通常与xor eax, eax一起使用。
rep movsb 一般用于赋值缓冲区中的字节。ESI需要被设为缓冲区地址,EDI被设为目的缓冲区地址,ECX则必须为要复制的长度。会逐字节复制,直至ECX=0。
rep scasb 用于在一段数据缓冲区中搜索一个字节。EDI需指向缓冲区地址,AL则包含要找的字节,ECX设为缓冲区长度。当ECX=0或找到该字节时,比较停止。
原文地址:https://www.cnblogs.com/Fingerprint/p/9899926.html