寄存器
存储cpu中的数据
32位通用寄存器
32位 | 16位 | 8位 |
EAX | AX | AL |
ECX | CX | CL |
EDX | DX | DL |
EBX | BX | BL |
ESP | SP | AH |
EBP | BP | CH |
ESI | SI | DH |
EDI | DI | BH |
8位寄存器在16位寄存器中,而16位寄存器在32位寄存器中。
简单来说
32位寄存器就是一整个
16位寄存器就是32的一半 15-0这部分
8位寄存器分高位和低位,分别代表15-8 7-0,如下图
做个实验就明白了
将32位寄存器全部写满数据
对16位寄存器调试
可以看到更改的数据是后面四个
对8位高低寄存器调试,可以看到ah是在eax寄存器的后34位改变的,al是后两位改变的
od添加两个指令
f8执行,eax的值变成了1 又把eax的值给了edx
写立即数到内存
mov byte ptr ds:[内存窗口的已申请的16进制],1
byte < word < dword 字节大小
mov byte ptr ds:[0019FB90],20
写寄存器到内存
mov byte ptr ds:[0019FB90],eax
读内存到寄存器
mov eax,byte ptr ds:[0019FB90]
内存地址的五种表示方式
形式1
立即数 0019FB90
形式2
[reg] 代表任意寄存器
形式3
[reg+立即数]
形式4
[reg+reg*{1,2,4,8}]
形式5
[reg+reg*{1,2,4,8}+立即数]
数据的存储模式
大段模式:数据高位在低位,数据地位在高位
小段模式:数据低位在低位,数据高位在高位
db 内存地址 查看一个字节
dw 内存地址 查看两个字节
dd 内存地址 查看四个字节
⼤⼩端的使⽤场景
1、Intel的80×86系列芯⽚使⽤⼩端存储模式
2、ARM芯⽚默认采⽤⼩端,但可以切换为⼤端
3、MIPS芯⽚采⽤⼤端,但可以在⼤⼩端之间切换
4、在⽹络上传输的数据普遍采⽤的都是⼤端
0x11223344 11是高位 44是低位
在内存地址中 90<93内存地址,所以是小段模式
0019FF90 44
0019FF91 33
0019FF92 22
0019FF93 11
mov eax,1 将1存储到eax中
mov eax,edx 将edx的值存储到eax
add eax,1 eax加1结果给eax
sub eax,1 eax减1结果给eax
按位与
作用:只将某一位变成0,而其他位保持不变
使用:谁要变0,谁就和0与
and就是与运算,两个数按二进制位相与,全1为1,有0为0,常用于把低位清零
or eax,edx
按位或
作用:只将某一位变成1,而其他位保持不变
使用:谁要变1,谁就和1或
xor eax,ecx
not eax,ecx
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
DF的值 由第十位决定
为0时,则EDI ESI +1 +2 +4
为1时,则EDI ESI -1 -2 -4
stos指令 将al/ax/eax的值存储到edi指定的内存单元
stos byte prt es:[EDI]
stos word prt es:[EDI]
stos dword prt es:[EDI]
简写
stosb
stosw
stosd
rep指令,按计数寄存器ECX中指定的次数重复执行字符串指令
mov ecx,10
rep movsd
rep stosd
ESP栈指针寄存器
相当于mov sub -4
push 3
push eax
push dword prt ds:[18FFA4]
相当于mov add +4
pop ecx
pop 3
修改EIP指令 下一次要执行的指令
jmp 004F11
jmp 10
jmp eax
修改EIP的值
call指令结束后,下一行地址存到堆栈中
同时ESP的值 -4
call 004F11
call eax
把当前栈顶的值放到EIP,ESP +4
ret
指令的集合
函数的调用
jmp 或 call
小案例 两数相加
001 mov ecx,1
002 mov edx,2
003 call 009
008 add ecx,edx
009 mov eax,ecx
010 ret
如果要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在ret指令之前,ESP指向的是我们压入栈中的地址。
如果通过堆栈传递参数 了,那么在函数执行完毕后,要平衡参数导致的堆栈变化。
001 push 1
002 push 2
003 call 007
004 add esp,8
007 mov eax,dword prt ss:[esp+4]
008 mov eax,dword prt ss:[esp+8]
009 ret
开辟新的内存空间 esp ebp整体移动,等函数调用结束在回到原位
001 push 1
002 push 2
003 call 007
004 add esp,8
007 push ebp
008 mov ebp,esp
009 sub esp,10
010 mov eax,dword ptr ss:[ebp+8]
011 mov eax,dword ptr ss:[esp+C]
012 mov esp,ebp
013 pop ebp
014 ret
标志寄存器
CF 第0位,表示无符号数运算的溢出状态,溢出为1,反之为0
溢出了 cf为1
mov al,0xFE
add al,2
PF 如果结果的最低有效字节包含偶数个1位,则为1,反之为0
mov al,0xce
add al,0
AF 如果算数操作在结果的第三位发生进位或借位则将该标志置1,否则清零
ZF 若结果为0,则为1,反之为0
mov eax,100
mov ecx,100
cmp eax,ecx
cmp与sub类似,但想减的结果并不保存到第一个操作数中
test eax,ecx
SF 该标志被设置为有符号整型的最高有效位(0 指示结果为正,反之则为负)
mov al,0x7F
add al,2
mov al,0xFE
add al,2
OF 反映有符号数加减运算所得结果是否溢出
如果无符号运算,溢出看cf位
如果有符号运算,溢出看of位
mov al,0x7F
add al,2
JCC指令 | 中文含义 | 检查符号位 |
JZ/JE | 若为0则跳转; | ZF=1 |
若相等则跳转 | ZF=1 | |
JNZ/JNE | 若不为0则跳转; | ZF=0 |
若不相等则跳转 | ZF=0 | |
JS | 若为负则跳转 | SF=1 |
JNS | 若为正则跳转 | SF=0 |
JP/JPE | 若1出现次数为偶数则跳转 | PF=1 |
JNP/JPO | 若1出现次数为奇数则跳转 | PF=0 |
JO | 若溢出则跳转 | OF=1 |
JNO | 若无溢出则跳转 | OF=0 |
JC/JB/JNAE | 若进位则跳转; | CF=1 |
若低于则跳转; | CF=1 | |
若不高于等于则跳转 | CF=1 | |
JNC/JNB/JAE | 若无进位则跳转; | CF=0 |
若不低于则跳转; | CF=0 | |
若高于等于则跳转; | CF=0 | |
JBE/JNA | 若低于等于则跳转; | ZF=1或CF=1 |
若不高于则跳转 | ZF=1或CF=1 | |
JNBE/JA | 若不低于等于则跳转; | ZF=0而且CF=0 |
若高于则跳转 | ZF=0而且CF=0 | |
JL/JNGE | 若小于则跳转; | SF != OF |
若不大于等于则跳转 | SF != OF | |
JNL/JGE | 若不小于则跳转; | SF = OF |
若大于等于则跳转; | SF = OF | |
JLE/JNG | 若小于等于则跳转; | ZF != OF 或 ZF=1 |
若不大于则跳转 | ZF != OF 或 ZF=1 | |
JNLE/JG | 若不小于等于则跳转; | SF=0F 且 ZF=0 |
若大于则跳转 | SF=0F 且 ZF=0 |
推荐阅读
APP逆向分析/渗透测试/安全检测/隐私合规如何选择手机机型或系统