第16节: 常用汇编指令
1、MOVS 指令:移动数据从内存到内存之间
BYTE/WORD/DWORD
MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
以上的简写形式是:MOVSB、MOVSW、MOVSD
MOVS是移动数据指令,跟MOV指令有一定的区别,MOV指令是从寄存器到内存、从内存到寄存器、从寄存器到寄存器的,而MOVS指令是给内存到内存,所以要明白不是所有的指令都是内存到内存,有些指令是可以的,有些指令是不可以的,这是第一个地方要注意的。那么第二个地方要注意的是,前面章节讲到的通用寄存器可以做任何的事情,但是有些通用寄存器有特殊的用途,比如:EBP是来做堆栈寄存器的等等,那这节将的EDI和ESI这两个寄存器是做什么用的呢?答案是来做内存到内存之间的移动的。就是我们在汇编里要把一片的数据移动到另一片空间里,也就是所为的串。这种串就用到了EDI和ESI,这两个寄存器在MOVS指令中是指定的,ESI存储的是一个地址或者说存储的是一个内存编号,EDI里面也是一个内存地址(编号)。MOVS指令的宽度可以是一个字节(BYTE)、二个字节(WORD)、四个字节(DWORD)。
例子:MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
ESI = 0x18FFC0 ESI中的BYTE=64 EDI = 0x18FFC4,DF =0
最后的0X18FFC4中的BYTE值是:64 ,ESI=0x18FFC1,EDI = 0x18FFC5
如果:ESI = 0x18FFC0 ESI中的BYTE =64 EDI = 0x18FFC4,DF=1
最后的0X18FFC4中的BYTE值是:64 ,ESI=0x18FFBF,EDI = 0x18FFC3
注意:值的变化,WORD和DWORD是一样的。
2、标志寄存器(EFL)
EFL也是32位寄存器,它里面每一个位代表的含义不一样,比如:十六进制的00000246对应的二进制是:0000 0000 0000 0000 0000 0010 0100 0110 它的第十位就是DF位也就是方向位,如果方向位是0有什么意义呢?当我们使用MOVS的指令的时候,如果方向为DF=0那每次执行的值加1或2和4,到底能加到几呢?这取决你的数据宽度,如果是DF=1的话每次都会减4或2和1。这就是方向位的含义。
3、STOS指令:
STOS BYTE PTR ES:[EDI]
STOS WORD PTR ES:[EDI]
STOS DWORD PTR ES:[EDI]
以上的简写形式是:STOSB、STOSW、STOSD
上面的指令是把AL/AX/EAX的值存储到指定的内存单元里,然后EDI的值也会加1或减1,加1或减1取决你的DF位,那么STOSB、STOSW、STOSD 分别是加1、加2、加4在内存中的值取决的是你设置的这三个指令。
例子:STOS BYTE PTR ES:[EDI]
EAX = 11223344 EDI = 0x18FFC0 DF = 0
最后的结果是EDI的BYTE值是44,EDI=0x18FFC1
如果方向为DF=1,那么EDI=0x18FFBF
注意:值的变化,WORD和DWORD是一样的。
4、REP指令
例子:
MOV ECX,10
REP MOVSD
REP 指令意思是重复几次,这要几次由寄存器ECX的值来定,上面的例子是有16次(十六进制的10次)。
例子:
MOV ECX,10
REP STOSD
REP指令的意思跟前的MOVSB和STOSB的意思一样的,前面的弄明白了后面的连续重复就明白了。
1、MOVS 指令:移动数据从内存到内存之间
BYTE/WORD/DWORD
MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
以上的简写形式是:MOVSB、MOVSW、MOVSD
MOVS是移动数据指令,跟MOV指令有一定的区别,MOV指令是从寄存器到内存、从内存到寄存器、从寄存器到寄存器的,而MOVS指令是给内存到内存,所以要明白不是所有的指令都是内存到内存,有些指令是可以的,有些指令是不可以的,这是第一个地方要注意的。那么第二个地方要注意的是,前面章节讲到的通用寄存器可以做任何的事情,但是有些通用寄存器有特殊的用途,比如:EBP是来做堆栈寄存器的等等,那这节将的EDI和ESI这两个寄存器是做什么用的呢?答案是来做内存到内存之间的移动的。就是我们在汇编里要把一片的数据移动到另一片空间里,也就是所为的串。这种串就用到了EDI和ESI,这两个寄存器在MOVS指令中是指定的,ESI存储的是一个地址或者说存储的是一个内存编号,EDI里面也是一个内存地址(编号)。MOVS指令的宽度可以是一个字节(BYTE)、二个字节(WORD)、四个字节(DWORD)。
例子:MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
ESI = 0x18FFC0 ESI中的BYTE=64 EDI = 0x18FFC4,DF =0
最后的0X18FFC4中的BYTE值是:64 ,ESI=0x18FFC1,EDI = 0x18FFC5
如果:ESI = 0x18FFC0 ESI中的BYTE =64 EDI = 0x18FFC4,DF=1
最后的0X18FFC4中的BYTE值是:64 ,ESI=0x18FFBF,EDI = 0x18FFC3
注意:值的变化,WORD和DWORD是一样的。
2、标志寄存器(EFL)
EFL也是32位寄存器,它里面每一个位代表的含义不一样,比如:十六进制的00000246对应的二进制是:0000 0000 0000 0000 0000 0010 0100 0110 它的第十位就是DF位也就是方向位,如果方向位是0有什么意义呢?当我们使用MOVS的指令的时候,如果方向为DF=0那每次执行的值加1或2和4,到底能加到几呢?这取决你的数据宽度,如果是DF=1的话每次都会减4或2和1。这就是方向位的含义。
3、STOS指令:
STOS BYTE PTR ES:[EDI]
STOS WORD PTR ES:[EDI]
STOS DWORD PTR ES:[EDI]
以上的简写形式是:STOSB、STOSW、STOSD
上面的指令是把AL/AX/EAX的值存储到指定的内存单元里,然后EDI的值也会加1或减1,加1或减1取决你的DF位,那么STOSB、STOSW、STOSD 分别是加1、加2、加4在内存中的值取决的是你设置的这三个指令。
例子:STOS BYTE PTR ES:[EDI]
EAX = 11223344 EDI = 0x18FFC0 DF = 0
最后的结果是EDI的BYTE值是44,EDI=0x18FFC1
如果方向为DF=1,那么EDI=0x18FFBF
注意:值的变化,WORD和DWORD是一样的。
4、REP指令
例子:
MOV ECX,10
REP MOVSD
REP 指令意思是重复几次,这要几次由寄存器ECX的值来定,上面的例子是有16次(十六进制的10次)。
例子:
MOV ECX,10
REP STOSD
REP指令的意思跟前的MOVSB和STOSB的意思一样的,前面的弄明白了后面的连续重复就明白了。