汇编笔记
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编笔记相关的知识,希望对你有一定的参考价值。
汇编笔记
?
1.调用约定
调用方式
应用
参数入栈顺序
回收堆栈
内外平栈
cdecl
C 语言
从右到左
调用者负责
外平栈
thiscall
C++语言 函数调用是ecx保存this指针
从右到左
被调用者负责
内平栈
stdcall
Windows Api函数
从右到左
被调用者负责
内平栈
fastcall
寄存器传参 ECX EDX 剩下参数入栈
从右向左
被调用者负责
内平栈
fastcallX64
寄存器传参 RCX,RDX,R8,R9 剩下参数入栈
从右向左
被调用者负责
内平栈
Pascal
?
从左到右
被调用者负责
内平栈
2.寻址方式
? 立即寻址方式 MOV EAH,1(直接给寄存器赋值)
? 寄存器寻址方式 MOV EAX,EBX
? 直接寻址 MOV EAX,DWORD PTR [0X42000] 取出地址中的值给EAX
? 寄存器间接寻址 MOV EAX,[ECX] MOV EAX,[ESI]
? 寄存器相对寻址 MOV EAX,[ESI+10H]
? 基址加变址寻址 MOV EAX,[EBX+ESI]
? 相对基址加变址 MOV EAX,[EBX+ESI+10H]
3.数据类型
类型
伪指令
数据宽度
?
整数
db
字节
BYTE
?
dw
字
WORD
?
dd
双字
DWORD
?
dq
四字
LONGLONG
浮点数
dt
10 bytes
80位
?
do
16 bytes
128位
4.寄存器
EAX:
? 累加寄存器,是很多加法乘法指令的缺省寄存器
? 存放函数返回值
? 大数运算时保存结果的低位
ECX:
? 计数器 重复指令REP 和LOOP 指令的内定计数器
EDX:
? 整数除法产生的余数
? 大数运算时保存结果的高位
EBX:
? 基地址寄存器
EBP:
? 保存栈底指针
? 寻找函数返回地址 [ebp+4]
? 寻找函数参数 [ebp+8],[ebp+12] 等
? 寻找函数局部变量 [ebp-4], [ebp-8] 等
ESP:
? 栈顶寄存器
ESI: 用于高速存储器传输指令,串操作常用,指向源串
EDI:用于高速存储传器输指令,串操作常用,指向目的串
X64 寄存器:
?
- 标志寄存器
? ZF 是不是0 是0 为True
? PF 奇偶标志位: 记录相关指令执行后,其结果的所有二进制位中1的个数是否为偶数。如果1的个数为偶数,PF=1,如果为奇数,那么PF=0。
?x
mov al,1
?
add al,10
?
执行后,结果为00001011B,其中有3(奇数)个1,则PF=0。
? SF 符号标志位:它记录相关指令执行后,其结果是否为负。如果结果为负,SF=1,如果非负,SF=0。
xxxxxxxxxx
mov al,10000001B
?
add al,1
?
执行后,结果为10000010B,符号位为1,则SF=1。
? CF 进位标志位:一般情况下,在进行了无符号运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。表示无符号数运算是否超出范围,结果仍然正确
xxxxxxxxxx
mov al,0ff
add al,1 ? ? ? ? ;执行后,(al) = 0, CF=1, CF记录了从最高有效位向更高位的进位值 OF =0
?
?
mov al,2
sub al,3 ? ? ? ? ? ;执行后,(al) = FFH, CF=1, CF记录了向更高位的借位值
?
? OF 溢出标志位。一般情况下,OF记录了有符号数运算的结果是否发生了溢出。如果发生溢出,OF=1,如果没有,OF=0。表示有符号数结果是否超出范围,运算结果已经不正确。
xxxxxxxxxx
mov al,7f ;127
add al,10 ;
add指令执行后:CF=0,OF=1。
? DF 方向标志位:决定串处理指令控制每次操作后si、di的增减。df=0,则每次操作后si、di递增,否则递减。
xxxxxxxxxx
带补例子
cld ; 将DF置为0
std ; 将DF置为1
? IF 中断标志位 决定CPU是否响应外部可屏蔽中断请求。IF为1时,CPU允许响应外部的可屏蔽中断请求
? TF 陷阱标志位 TF被设置位1时,CPU进入单步模式,所谓单步模式就是CPU在每执行一步指令后都产生一个单步中断。主要用于程序的调试。
? AF 辅助进位标志位 在字节操作时低半字节向高半字节进位或借位。字操作时低字节向高字节进位或借位,AF置1,否则置0。
?
6.JCC
近跳转 - 跳转到当前代码段(CS 寄存器当前指向的段)内的指令,有时称为段内跳转。64k范围
短跳转 - 跳转范围限制为距当前 EIP 值 -128 到 +127 单位:字节, 的近跳转。
远跳转 - 跳转到当前代码段以外的段(但特权级别相同)中的指令,有时称为段间跳转。
注 JCC 指令不支持远跳转 ,
xxxxxxxxxx
远跳转可使用组合跳转
JNZ BEYOND;
JMP FARLABEL;
BEYOND:
?
? J : 表示 jump 转移
? E: 表示 equal 等于
? NE: 表示 not equal 不等于
? B: 表示 below 小于
? NB:表示 not below 不小于
? L: 表示 low 小于
? NL:表示 not low 不小于
? A: 表示 above 大于
? NA:表示 not above 不大于
? G :表示 大于
? NG:表示 不大于
?
?
7.几个 指令
LEA: 取地址
xxxxxxxxxx
lea eax,dword ptr[num] ? ;eax 中是num 的地址
mov ebx,num
lea ecx,[ebx] ? ;ebx 中是什么就是什么
[ ] : 间接取操作数方式 限于寄存器 , 在8086中 [ ] 只能 si di bx bp ,但在win32中好像并没有做限制
xxxxxxxxxx
? lea esi,dword ptr [num] ? ;num 地址放入 esi 中
? mov eax,num ? ? ? ? ? ?
? mov edx,20d
? mov [esi],edx ? ? ? ? ? ? ;edx 的值 放入esi指向的内存中
? mov esi,edx ? ? ? ? ? ? ? ;esi=edx
?
? lea esi,dword ptr [num] ? ;num 地址放入 esi 中
? mov eax,[esi] ? ? ? ? ? ? ;取esi内容 放到eax中 eax=10h
? mov ecx,esi
? mov edx,[ecx] ? ? ? ? ? ? ;取ecx内容 放到edx中 edx=10h
? mov ecx,[num1] ? ? ? ? ? ;ecx 存放 num1 的值
?
offset : 伪指令, 取偏移 在编译时确定,不能用于局部变量
addr : 伪指令, invoke 伪指令 中用到 取 地址
?
8.框架识别
?
8.1 VS 201X RELEASE 版 控制台 MAIN 函数识别 三个push 一个call
注:其他自己总结
xxxxxxxxxx
int main( int argc, char argv[], char envp[] )
?
xxxxxxxxxx
0131127C ? . 50 ? ? ? ? ? PUSH EAX ? ? ? ? ? ? ? ;整数, 为传给main()的命令行参数个数。
?
0131127D ? . FF37 ? ? ? ? PUSH DWORD PTR DS:[EDI];字符串数组
?
0131127F ? . FF36 ? ? ? ? PUSH DWORD PTR DS:[ESI];envp是系统的环境变量(也是字符串)
?
01311281 ? . E8 EAFDFFFF ? CALL ConsoleA.01311070
?
8.2 while 循环
xxxxxxxxxx
? char*str = "HelloBoy";
int i = 0;
while (i < strlen(str))
{
printf("%c",str[i]);
i++;
}
?
8.2.1 指针
?
8.3 doWhile
xxxxxxxxxx
do
{
printf("%c", str1[k]);
k++;
} while (k < strlen(str1));
?
?
8.4 switch
?
8.5 扩展
常见表达式语句的反汇编(x86) https://bbs.pediy.com/thread-224347.htm
常见指针和数组的反汇编(x86) https://bbs.pediy.com/thread-224346.htm
以上是关于汇编笔记的主要内容,如果未能解决你的问题,请参考以下文章