基础知识
一堆干货,哈哈哈哈
寄存器:
ESP:指向堆栈最顶端的地址
EIP:指向当前将要执行的命令
在OD中寄存器以十六进制显示内容 最小值:00000000,最大值:FFFFFFFF 负数表示: 00000000到7FFFFFFF为正数 80000000到FFFFFFFF为负数 FFFFFFFF表示-1,FFFFFFFE表示-2
标志寄存器:
O标志(溢出标志):当指令的结果超出了他可能存取的最大值,将被设置
A标志(辅助进位标志)
P标志(奇偶标志):如果指令结果用二进制表示,当1的个数为偶数时被设置
Z标志(零标志):当运算结果为0时被设置
S标志(符号标志):运算结果为负时被设置
C标志(进位标志)
被设置意味为“1”
汇编指令:
NOP指令:没有任何操作
PUSH指令:入栈,将操作数压入堆栈中
push 0 就是把0存入堆栈的顶部,这样的话栈窗口最顶的值成了00000000而其他的没有变化
同时ESP发生了变化,因为下一条要执行的指令成了刚刚堆上的数据
push [401008] 表示把401008这个内存单元中存储的内容压入
POP指令:出栈,取出堆栈顶部的值,然后存放到指定的目标地址内存单元中
pop eax 将栈顶的值放到eax
PUSHAD指令:把所有通用寄存器的内容按一定顺序压入堆栈中
先是push eax,依次向下,所以结束后eax的值应该在这些的最下面
POPAD指令:与PUSHAD相反,从堆栈中取值,放到相应寄存器中
先把最上面给最下面的寄存器,结束后原本是eax的还是在eax
MOV指令:将第二个操作数,赋值给第一个操作数
mov eax,1 把1赋值给eax
mov dword ptr ds:[400500],eax会发生异常,因为要写入400500这个内存地址导致的内存访问异常
mov eax,dword ptr ds:[400500]就可以
MOVSX指令:带符号扩展的传送指令,第一个操作数的位数比第二个操作数多,第二个操作数的符号位填充第一个操作数剩余部分
如果把movsx eax,bx eax=00000000 bx=F000
执行后eax成了FFFFF000
因为F000是负数,所以填充FFFF,如果bx是7FFF那么执行后eax是00007FFF
16位与32位的16进制正负概念是一样的,0000到7FFFF是正数,8000到FFFF是负数
MOVZX指令:剩余部分总是被填充为0
LEA指令:取地址指令,类似于MOV但是第一个操作数是通用寄存器,第二个操作数是一个内存单元
LEA eax,dword ptr ds:[ecx+38] 假设ecx值为12FFB0
那么只需要将12FFB0+38的值12FFE8赋值给eax,而不需要获取ecx+38指向内存的值
XCHG指令:交换两个操作数的值
数学指令:
INC 和 DEC:INC加1,DEC减1
ADD:有两个操作数,相加后结果放到第一个操作数中
ADC:带进位的加法,两个操作数的和加上进位的标志,结果放到第一个操作数中(进位标志是 C
SUB:第一个操作数减去第二个操作数的结果,放到第一个操作数中
SBB:计算两个操作数的差值,还要减去进位标志
MUL:无符号数的乘法,只有一个操作数,另一个始终是eax,结果存放到EDX:EAX中,即EAX存不下的高位放在EDX中
IMUL:有符号数的乘法,有符号数的数,乘以EAX
DIV/IDIV:无符号除法和有符号除法
XADD:交换相加,先交换,再相加,再保存到第一个操作数
NEG:将操作数的符号取反
逻辑指令:
AND:只有两个二进制位都为1时结果才为1,其他情况都为0
如:01001000000000
和:11010100000000执行AND以后
为:01000000000000
OR:只要有一个是1就为1
XOR:相同时为0,不同时为1,结果放到第一个操作数中
NOT:简单的安位取反 not 1 = 0 not 01001 = 10110
比较和条件跳转:
零标志位:Z
CMP:相当于第一个操作数减第二个操作数,当两个数相等时,结果为0,零标志位为1,当两个操作数不相等时,结果为非0,零标志位为0
S标志位是用来记录第一个操作数是否大于第二个操作数,大于就是0,即负为1,正为0
P:奇偶标志位,结果中1的个数为偶数则为1
O:溢出标志位,溢出为1
TEST:逻辑比较
跳转:
JMP:跳转,无条件跳转
JE,JZ:结果为0跳转,Z标志位为1则跳转
JNE,JNZ:结果不为0跳转,Z标志位为0则跳转
JS:结果为负跳转,S标志位为1
JNS:结果不为负跳转,S标志位为0
跳转太多了,不列举了,没意义
CALL和RET:
CALL相当于子程序
RET会返回到栈窗口最上面的地址
直接在栈窗口选中回车就可以知道在哪里调用的
循环:
1.label
XOR ECX, ECX
MOV ECX, 15H
LABEL:
DEC ECX
CMP ECX, 0
JNE LABEL
2.loop
mov cx,10 #每一次loop cx自动减1
mov ax,2
add ax,ax
loop 地址
串操作:
MOVS:从一个地址向另一个地址复制数据,源地址保存在ESI寄存器中,目标地址保存在EDI
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
REP:可以作为以上指令的前缀,该前缀表示当前指令需要执行的次数ECX,每次循环,ECX减一,配合MOVS使用时,总共可以拷贝的大小为每次拷贝大小*ECX
MOV ECX,4
REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
LODS:从源地址ESI拷贝到EAX中
MOV ECX,4
LODS DWORD PTR DS:[ESI]
STOS:将EAX的值拷贝到EDI指向的内存单元
CMPS:比较ESI和EDI指向内存单元的内容
CMPS DWORD PTR DS:[ESI],DWORD PTR ES:[EDI]
寻址方式:
直接寻址:
该指令操作数中包含具体地址
如:mov eax,dword ptr [401000]
间接寻址:
mov dword ptr[eax],ecx
call eax
jmp [ebx + 4]
使用间接寻址,只能在执行者条指令的时候获取当前的值,因为还不知道ebx是什么
END