汇编指令学习笔记
常用汇编指令
| 指令 | 说明 |
|---|---|
JMP |
修改EIP的值 |
CALL |
修改EIP的值,将下一个指令的地址压入栈中,并减少ESP的值 |
RET |
将栈顶内存写入EIP,并增加ESP的值,栈顶内存储存的是CALL执行前的下一步地址 |
CMP |
等同于SUB,但结果不保存 |
TEST |
同上,等同于AND |
内存相关指令
MOV BYTE PTR DS:[0018FFF0],1
将立即数储存到0X0018FFF0开始的一字节空间,在写入内存时必须声明长度。
在汇编中的数据类型有BIT(1位),BYTE(1字节),WORD(2字节),DWORD(4字节)
MOV DWORD PTR DS:[0019FF74],EAX
将32位通用寄存器EAX的值写到0X0019FF74,写入的宽度必须和寄存器的宽度一致
MOVS指令
MOV 指令无法从内存写到内存
32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。
寄存器
ESI、EDI、SI和DI称为变址寄存器(Index Register)其中S和D代表source和destination
它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。变址寄存器不可分割成8位寄存器。
1 | MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] |
可以简写成MOVSB,MOVSW,MOVSD,ES是extra segment的缩写,执行以上命令,会将寄存器ESI中指向内存的数据储存到EDI指向的内存中,执行完毕后EDI和ESI两个寄存器中的地址会自动增加,增加的数取决于附加数据的长度,以上三条指令分别会使变址寄存器中的值增加1、2、4
在使用时
EDI必须作为储存附加段地址寄存器,ESI作为储存数据段地址的寄存器
例如有以下命令
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]

此时变址寄存器中指向的内存

执行完毕后两个变址寄存器的值增加了4,因为写入了4字节数据,内存往后移4字节。
STOS指令
将AI、AX、EAX的值储存到EDI指向的内存单元,例如数据长度为BYTE,则会将AI的值写入到EDI指向的内存
1 | STOS BYTE PTR ES:[EDI] |
可以简写成STOSB、STOSW、STOSD
执行完毕后EDI的值增加(或减少,取决于DF标志位),增加的量取决于数据长度。
REP指令
REP(repeat)
按计数寄存器ECX中指定的次数重复执行字符串指令,每执行一次时ECX减一
1 | MOV ECX,10 |
以上第二行指令将ESI指向的内存数据(32位)写入到EDI寄存器,然后变址寄存器+4,此步骤重复16次 (指令中的10为16进制)
第三行将EAX指向的内存数据(32位)写入到EDI寄存器,然后EDI+4,此步骤重复16次
函数相关命令
使用寄存器传递参数
1 | MOV ECX,1 |
堆栈传参
需要注意的是最后一个被压栈的是函数地址,所以取值的时候需要加上一个偏移量
1 | PUSH 1 |
