汇编pushedi
A. 请大家帮我解释下这个汇编程序的意思
0051A038 push ebp
0051A039 mov ebp, esp ;开辟新的堆栈
0051A03B add esp, $FFFFFEE0 ;为参数开辟空间
0051A041 push ebx
0051A042 push esi
0051A043 push edi
0051A044 xor ecx, ecx ;清空ecx
0051A046 mov [ebp+$FFFFFEE0], ecx
0051A04C mov [ebp+$FFFFFEE4], ecx
0051A052 mov [ebp+$FFFFFEE8], ecx
0051A058 mov [ebp+$FFFFFEEC], ecx
0051A05E mov [ebp-$0C], ecx
0051A061 mov [ebp-$10], ecx
0051A064 mov [ebp-$04], ecx
0051A067 mov [ebp-$08], ecx ;把函数参数压栈,全部是0
0051A06A mov ebx, eax
0051A06C xor eax, eax ;清空eax
0051A06E push ebp
0051A06F push $0051A2A1
0051A074 push dword ptr fs:[eax]
0051A077 mov fs:[eax], esp ;设置新的seh
0051A07A lea eax, [ebp-$04] ;把ebp-$04的参数传到eax
0051A07D mov edx, [$534BAC] ;把$534BAC地址的数据放到edx
0051A083 call 00404140 ;调用函数404140
0051A088 mov eax, [ebp-$04]
0051A08B push eax ;保存eax
0051A08C lea eax, [ebp-$08] ;获得ebp-$08的地址
0051A08F mov edx, [$5350C0] ;把$5350c0地址的数据放到edx
0051A095 call 00404140 ;调用函数404140
0051A09A mov eax, [ebp-$08]
0051A09D pop edx
0051A09E call 00488D1C ;调用函数488d1c
0051A0A3 test eax, eax ;测试返回值是否为0
0051A0A5 jle 0051A0B6 ;小于或等于跳
0051A0A7 mov dword ptr [ebx+$0234], $00000006
0051A0B1 jmp 0051A266 ;跳到0051A266
0051A0B6 lea edx, [ebp-$0C]
0051A0B9 mov eax, [ebx+$02EC]
0051A0BF call 004352A8 ;调用函数4352a8
0051A0C4 mov eax, [ebp-$0C]
0051A0C7 push eax
0051A0C8 lea eax, [ebp-$10]
0051A0CB mov edx, [$534BAC]
0051A0D1 call 00404140 ;调用函数404140
0051A0D6 mov edx, [ebp-$10]
0051A0D9 pop eax
0051A0DA call 00488D1C ;调用函数488d1c
0051A0DF test eax, eax ;测试返回值是否为0
0051A0E1 jnz 0051A101
0051A0E3 push $30
B. OD工具如何查找特定的汇编指令如:MOV edi,edi 这样的
所有来指令序列查找范围是自当前CPU窗口所在的内存段。
Ctrl+G,然后输入401000,回车,然后你再找
你先得跳到你要找的代码所在的内存段,EXE是从401000开始的,如果是DLL的话,得按Alt+E,查看模块的基址,然后跳到基址之后再查找
C. 求汇编指令解释dec edx
add byte ptr ds:[eax],al ;将AL寄存器中的内容存入段寄存器DS定位的,由EAX寄存器指向的内存单元.
push edi ;将EDI寄存器压入堆栈,注意是四个字节
push ds ;将DS寄存器压入堆栈,注意是两个字节
dec edx ;让EDX寄存器自减一,即 EDX <- (EDX)-1
D. 函数调用堆栈原理 push ebx push esi push edi是什么作用
[cpp] view plain
int goo(int a, int b)
{
return a + b;
}
void foo()
{
int a[] = {1, 2, 3};
int result = goo(a[1], a[2]);
printf("result: %d", result);
}
VS2010下编译
foo函数部分汇编:
[cpp] view plain
00EB3890 push ebp
00EB3891 mov ebp,esp
00EB3893 sub esp,0E4h
00EB3899 push ebx
00EB389A push esi
00EB389B push edi
00EB389C lea edi,[ebp-0E4h]
00EB38A2 mov ecx,39h
00EB38A7 mov eax,0CCCCCCCCh
00EB38AC rep stos dword ptr es:[edi]
00EB38AE mov eax,dword ptr [___security_cookie (0EB7000h)]
00EB38B3 xor eax,ebp
00EB38B5 mov dword ptr [ebp-4],eax
int a[] = {1, 2, 3};
00EB38B8 mov dword ptr [ebp-14h],1
00EB38BF mov dword ptr [ebp-10h],2
00EB38C6 mov dword ptr [ebp-0Ch],3
int result = goo(a[1], a[2]);
00EB38CD mov eax,dword ptr [ebp-0Ch]
00EB38D0 push eax
00EB38D1 mov ecx,dword ptr [ebp-10h]
00EB38D4 push ecx
00EB38D5 call goo (0EB11E5h)
00EB38DA add esp,8
goo函数完整汇编:
[cpp] view plain
00EB1580 push ebp
00EB1581 mov ebp,esp
00EB1583 sub esp,0C0h
00EB1589 push ebx
00EB158A push esi
00EB158B push edi
00EB158C lea edi,[ebp-0C0h]
00EB1592 mov ecx,30h
00EB1597 mov eax,0CCCCCCCCh
00EB159C rep stos dword ptr es:[edi]
return a + b;
00EB159E mov eax,dword ptr [a]
00EB15A1 add eax,dword ptr [b]
}
00EB15A4 pop edi
00EB15A5 pop esi
00EB15A6 pop ebx
00EB15A7 mov esp,ebp
00EB15A9 pop ebp
00EB15AA ret
foo函数push ebp, mov ebp, esp后
保存原ebp,设定新的ebp为当前esp位置
sub esp, 0E4h
给局部变量分配足够大的栈空间
保存原先的一些寄存器值,每次push,esp继续向下移
为局部变量a数组赋值
调用goo前Push两个参数,esp继续下移
call goo函数时,cpu自动push下一条指令地址,esp继续下移
在goo函数中,同样保存foo函数中的ebp值,设定新的ebp,esp等
在执行玩goo函数最后几句指令时,edi, esi, ebx恢复,esp同时也编程goo中ebp的位置,ebp恢复至foo函数原来的位置(pop ebp)
下一条指令也装入IP(ret指令),esp继续向上一步
foo函数中的add esp, 8将esp值继续往上(清除函数参数)
清除函数参数的工作也可通过ret X在goo函数返回时设定(这样的话不必在每次调用点上加上add esp, X指令缩短了编译出来的文件大小,但在子函数中清除将不能做到printf等的可变参数个数功能,因为子函数不知道具体有多少要参数进入了,只有调用处才知道)
E. 反汇编小白求知:push esi push edi push 9 push r10 pop edi 然后。。。。。会怎样
push esi //esi进栈
push edi //edi进栈
push 9 //9进栈
push 10 //10进栈
pop edi //10出栈保存到edi中
//栈中的数据变成了
9
edi
esi
----------没啥意思的。没事到0x30网络贴吧耍耍, 一起讨论分享交流编程技术。
F. 汇编语言用指令PUSHA到底把、哪些压栈了呢
如果是51单片机,那么没有PUSH A指令,可以是PUSH Acc。进栈时,看你的SP开在什么地方,先要对SP加1,再进栈。
例如:MOV SP,#60H
PUSH ACC
那么,执行PUSH ACC时,先SP+1,那么SP指向61H,然后将ACC的内容推入61H中!
G. 汇编语言指令大全,要详细的 !!!!
一、数据位传送指令:
1、MOV C, bit ;bit 可直接寻址位 C←(bit)
2、MOV bit,C ;C 进位位 (bit) ← C
二、位变量修改指令:
1、CLR C ; 将C=0
2、CLR bit
3、CPL C ; 将C求反再存入C
4、CPL bit ; 将bit求反再存入bit
5、SETB C ; 将C=1
6、SETB bit ; (bit) ← 1
三、位变量逻辑指令:
ANL C, bit ANL C, bit ORL C, bit ORL C, bit
H. 反汇编,不知道这段是什么意思。请大侠帮忙
晕乎啊。
数据传送指令 MOV
格式: MOV OPRD1,OPRD2
----
功能: 本指令将一个源操作数送到目的操作数中,即OPRD1<--OPRD2.
堆栈操作指令 PUSH和POP
格式: PUSH OPRD
---- POP OPRD
功能: 实现压入操作的指令是PUSH指令;实现弹出操作的指令是POP指令.
测试指令 TEST
格式: TEST OPRD1,OPRD2
----
功能: 其中OPRD1、OPRD2的含义同AND指令一样,也是对两个操作数进行按位的'与'运算,唯一不同之处是不将'与'的结 ---- 果送目的操作数,即本指令对两个操作数 的内容均不进行修改,仅是在逻辑与操作后,对标志位重新置位.
TEST与AND指令的关系,有点类似于CMP与SUB指令之间的关系.
条件转移指令JNE/JNZ
格式: JNE/JNZ 标号
----
功能: ZF=0,转至标号处执行
----说明: 1. 指令JNE与JNZ等价,它们是根据标志位ZF进行转移的指令
----
2. JNE,JNZ均为一条指令的两种助记符表示方法
I. 汇编指令的数据传输
它们在存储器和寄存器、寄存器和输入输出端口之间传送数据。
1. 通用数据传送指令
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )
XADD 先交换再累加.( 结果在第一个操作数里 )
XLAT 字节查表转换.
── BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即
0-FFH); 返回 AL 为查表结果. ( [BX+AL]->AL )
2. 输入输出端口传送指令.
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )
输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,
其范围是 0-65535.
3. 目的地址传送指令.
LEA 装入有效地址.
例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.
例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.
例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.
例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.
例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.
例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.
J. 汇编pushad可以替换成什么
Push EAX
Push ECX
Push EDX
Push EBX
Push EBP
Push ESI
Push EDI