标志寄存器 EFL
EFL是32位寄存器
其中的每一位,含义都是不同的
0x00000246 16进制
0000 0000 0000 0000 0000 0010 0100 0110 二进制
第十位(从下标开始算 从右往左):DF位
DF位为``的时候: MOVS 执行完毕之后 ESI和EDI的值会增加
DF位位1
的时候: MOVS 执行完毕之后 ESI和EDI的值会减少
修改标志寄存器中D位的值,然后在执行下面的指令
MOV EDI,12FFD8
MOV ESI,12FFD0
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 观察EDI和ESI的值
MOV EAX,12345678
MOV EDI,12FFC4
STOS BYTE PTR ES:[EDI] 观察EDI的值
STOS WORD PTR ES:[EDI]
STOS DWORD PTR ES:[EDI]
MOVS指令:移动数据 内存-内存
BYTE/WORD/DWORD
MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 简写:MOVSB
MOVS WORD PTR ES:[EDI],BYTE PTR DS:[ESI] 简写:MOVSW
MOVS DWORD PTR ES:[EDI],BYTE PTR DS:[ESI] 简写:MOVSD
例子:
MOV EDI,12FFD8
MOV ESI,12FFD0
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 观察EDI的值
在汇编中,当我们需要把内存中的数据从一个地方复制到另一个地方的时候就会用到
EDI和ESI
ESI中存储需要复制的数据的内存地址,EDI是将要复制的地方
MOVS指令每执行一次,EDI和ESI的大小就自动增加或减少 取到内存中值的数据宽度大小
如果是 movs dword ***
那么每次就增加或减少4
如果是 movs word ***
那么每次就增加或减少2
如果是 movs byte ***
那么每次就增加或减少1
STOS指令:AI/AX/EAX的值存储到[EDI]指定的内存单元
STOS BYTE PTR ES:[EDI] 简写: STOSB
STOS WORD PTR ES:[EDI] 简写: STOSW
STOS DWORD PTR ES:[EDI] 简写: STOSD
将寄存器EAX中的值放到EDI指定的内存中去
这里根据取不同的宽度所以取EAX中不同的位数
BYTE = AI
WORD = AX
DWORD = EAX
MOV EAX,12345678
MOV EDI,12FFC4
STOS BYTE PTR ES:[EDI] 观察EDI的值和EDI对应内存中的值
STOS WORD PTR ES:[EDI]
STOS DWORD PTR ES:[EDI]
STOS 每执行一次,EDI的值就自动增加或者减少
如果是 stos byte ...
那么每次就增加或减少1
如果是 stos word ...
那么每次就增加或减少2
如果是 stos dword ...
那么每次就增加或减少4
REP指令:按计数寄存器(ECX)中指定的次数重复执行字符串指令
上面的MOVS指令和STOS指令一次最多也只能移动4个字节,如果想移动大片的内存,那么就需要REP指令了
按计数寄存器(ECX)中指定的次数重复执行字符串指令,计数完毕后ECX会置零
MOVS ECX,0x10 ->16进制 "10" 对应10进制 16 也就是执行16次
REP MOVSD
MOVS ECX,0x10
REP STOSD
延伸
通用寄存器的通常用处:
EAX
通常用来作为返回值
ECX
通常用来作为计数器
ESP EBP
通常用来作为 堆栈
的栈顶和栈低
ESI EDI
通常用做内存 复制的源地址和目标地址