|
mov的寻址方式
知识点:
⦁ 立即寻址
⦁ 寄存器寻址
⦁ 寄存器间接寻址
⦁ 直接寻址方式
⦁ 寄存器相对寻址
一、了解指令常用寻址方式
寻址方式就是寻找操作数或操作数地址的方式。
寄存器是中央处理器内的组成部分。寄存器是一组容量有限的高速存贮部件,它们可用来暂存指令、数据和位址。(DWORD)
MOV EAX,0x1234 //立即寻址
MOV EAX,EBX //寄存器寻址 数据寄存器,一般称之为通用寄存器组 通用寄存器有4个 EAX,EBX,ECX,EDX
MOV EAX,[EBX] //寄存器间接寻址
MOV EAX,v //v是一个变量名
MOV EAX,[1234] //直接寻址方式
MOV EAX,[EBX+1234] //寄存器相对寻址
二、理解寻址
上边的名字看起来很多,总结起来也就2种方式:
带[]与不带[]
1、不带括号的 有立即数与寄存器
2、带括号的就是指针,从地址里边取值出来。
MOV EAX,0x1234 //立即寻址 eax=0x1234;
MOV EAX,EBX //寄存器寻址 eax=ebx
MOV EAX,[EBX] //寄存器间接寻址 eax=*(int*)ebx;
MOV EAX,v //v是一个变量名 eax=v; //被编译后 一般会呈后边两种形式
MOV EAX,[1234] //直接寻址方式 eax=*(int*)(0x1234)
MOV EAX,[EBX+1234] // 寄存器相对寻址 eax=*(int*)((int)ebx+1234); //这里的1234称为偏移,EBX是基址
三、对调位置
MOV EAX,0x1234 //立即数不能出现在MOV指令左边。如: MOV 0x1234,EAX 这是错的写法
后边的都可以对换位置
MOV EAX,EBX //寄存器寻址 eax=ebx mov ebx,eax
MOV EAX,[EBX] //寄存器间接寻址 eax=*(int*)ebx; mov [ebx],eax
MOV EAX,v //v是一个变量名 eax=v; mov v,eax
MOV EAX,[1234] //直接寻址方式 eax=*(int*)(0x1234) mov [1234],eax
MOV EAX,[EBX+1234] // 寄存器相对寻址 eax=*(int*)((int)ebx+1234) mov [ebx+1234],eax
四、代码测试
int *da=a;//int a[0x10]={0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xd,0xe};
//提示 在命令栏中用 dd 地址表达式 可以以DWORD 4字节格式显示指定地址的数据
__asm
{
mov eax,0x1111
mov ebx,eax
mov ebx,bbb //全局变量bbb
mov ebx,da //取数组基址
mov eax,[da+4]
mov eax,[ebx+4]
}
//下边指令,前边是寄存器相对寻址,后边是立即寻址
0040105A |. C745 FC 20304>MOV DWORD PTR SS:[EBP-4],001_MOV.00403020 ; int *da=a //a是数组的地址
00401061 |. B8 11110000 MOV EAX,1111 ; eax=0x1111 立即寻址
00401066 |. 8BD8 MOV EBX,EAX ; mov ebx,0x1111-->ebx=0x1111 //寄存器寻址
00401068 |. 8B1D 18304000 MOV EBX,DWORD PTR DS:[403018] ; mov ebx,008899FF-->ebx=009988FF 直接寻址
0040106E |. 8B5D FC MOV EBX,DWORD PTR SS:[EBP-4] ; mov ebx,da 寄存器 相对寻址
00401071 |. 8B45 00 MOV EAX,DWORD PTR SS:[EBP] //寄存器间接寻址
00401074 |. 8B43 04 MOV EAX,DWORD PTR DS:[EBX+4] ; eax=da[1]=1 寄存器 相对寻址
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------以上摘自郁金香汇编逆向与外挂教程。
通过od反汇编c语言代码来分析寻址方式:
vs中关闭编译优化,release下编译以下代码
[C] syntaxhighlighter_viewsource syntaxhighlighter_copycode #include <stdio.h>
#include <windows.h>
int num;
int main()
{
int a, b, c;
int d[] = { 0, 1, 2, 3 };
MessageBox(NULL,"","",MB_OK);
num = 20;
a = 10;
b = a;
c = d[0];
c = d[1];
c = d[2];
system("pause");
return 0;
}
在od中通过MessageBoxW定位到这些变量的赋值操作。
mov的寻址方式
[C] syntaxhighlighter_viewsource syntaxhighlighter_copycode 00E21040 C705 8833E200 1>mov dword ptr ds:[num],0x14
00E2104A > C745 E4 0A00000>mov dword ptr ss:[ebp-0x1C],0xA
00E21051 8B45 E4 mov eax,dword ptr ss:[ebp-0x1C]
00E21054 > 8945 E0 mov dword ptr ss:[ebp-0x20],eax
00E21057 B9 04000000 mov ecx,0x4
00E2105C 6BD1 00 imul edx,ecx,0x0
00E2105F 8B4415 EC mov eax,dword ptr ss:[ebp+edx-0x14]
00E21063 8945 E8 mov dword ptr ss:[ebp-0x18],eax
00E21066 B9 04000000 mov ecx,0x4
00E2106B C1E1 00 shl ecx,0x0
00E2106E 8B540D EC mov edx,dword ptr ss:[ebp+ecx-0x14]
00E21072 8955 E8 mov dword ptr ss:[ebp-0x18],edx
00E21075 B8 04000000 mov eax,0x4
00E2107A > D1E0 shl eax,1
00E2107C 8B4C05 EC mov ecx,dword ptr ss:[ebp+eax-0x14]
00E21080 894D E8 mov dword ptr ss:[ebp-0x18],ecx
逐行分析。。
mov dword ptr ds:[num],0x14
立即寻址 num=20
mov dword ptr ss:[ebp-0x1C],0xA
寄存器间接寻址
ebp 百度词条 http://baike.baidu.com/view/1384237.htm
我的理解就是栈顶指针,0x1c 是 十进制的28
ebp-0x1c 寻址,也就是变量a的地址,我们可以算下:
从下往上看,ebp-4是最后一个局部变量的地址(Release 编译无优化的情况下).
定义了int型数组d ,d本身占用了四个字节,d有四个数组成员,4*4+4+4=24,
为了方便理解我们可以看下在od中数组d的定义:
mov的寻址方式
然后
[C] syntaxhighlighter_viewsource syntaxhighlighter_copycode int a,b,c ;
24+4=28,也就是ebp-0x1c 是a的地址。
a=10;
mov eax,dword ptr ss:[ebp-0x1C]
相对寻址 eax=a;
mov dword ptr ss:[ebp-0x20],eax
相对寻址
ebp-0x20 b的地址
b=eac;
mov ecx,0x4
立即寻址
ecx=0x4
imul edx,ecx,0x0
imul 乘法 百度词条http://baike.baidu.com/view/4980399.htm
edx=0x4*0 ,edx=0
mov edx,dword ptr ss:[ebp+ecx-0x14]
寄存器相对寻址
edx=ebp+ecx-0x14
edx=ebp-0x14
edx=d[0]
edx=0
mov dword ptr ss:[ebp-0x18],eax
相对寻址
ebp-0x18 =eax
c=0
mov ecx,0x4
立即寻址
ecx=0x4
shl ecx,0x0
shl 左移 百度词条http://baike.baidu.com/subview/1274191/7944058.htm
4左移0位 不变
ecx=0x4
mov edx,dword ptr ss:[ebp+ecx-0x14]
相对寻址
edx=ebp- 0x10
edx=d[1]
edx=1
mov dword ptr ss:[ebp-0x18],edx
相对寻址
c=1
mov eax,0x4
立即寻址 eax=0x4
shl eax,1
eax<<1
eax=8
mov ecx,dword ptr ss:[ebp+eax-0x14]
相对寻址
exc=ebp-0xc
exc=d[2]
exc=2
mov dword ptr ss:[ebp-0x18],ecx
c=2
分析结束。。。
总结一下,寻址的方式不重要,重要的是这个寻址寻的是谁的地址。。。
|
上一篇: c语言内联汇编实现变量赋值下一篇: 什么是call
|