一、为什么要寻址
- 我们知道数据存储在内存中,CPU需要使用存在内存中的数据,使用一个数据就要在内存中找到这个数据,用什么找,就是用内存编号,即地址,来找到数据在内存中所在的位置,把它取出来使用,或者再放回到指定位置
- 上述就是一个寻址过程:寻址方式一共有五种,计算机只认识这五种方式来寻址
二、五种寻址方式
1.寻址方式一[立即数]
-
直接通过[立即数],即直接用内存地址来寻址
-
读取内存的值
MOV EAX,DWORD PTR DS:[0x13FFC4]MOV就是将DWORD PTR DS:[0x13FFC4]这个值放到32位EAX寄存器中;DWORD表示读32位的数字,可以省略但不建议;PTR是固定写法;DS是段寄存器,32位汇编中段寄存器和内存的属性有关系,如果后面地址直接用数表示,则用DS,如果后面写ESP或者EBP,就写SS,如果EDI的话就用ES。所以32位汇编中段寄存器就是后面内存属性的一个标识。所以整条指令的作用就是用立即寻址的方式将内存中0x13FFC4地址中存储的值读出来放到EAX里
-
向内存中写入数据
MOV DWORD PTR DS:[0x13FFC4],ebx将内存中0x13FFC4中的值读出来写入到ebx寄存器中
-
获取内存编号
LEA EAX,DWORD PTR DS:[0x13FFC4]第一条指令表示将内存中0x13FFC4这个地址编号放入到EAX寄存中
2.寻址方式二[reg]
-
通过[reg]来寻址,reg可以是8个通用寄存器中的任意一个。先通过读取寄存器中存放的内存地址编号,再通过内存地址编号找到内存中的值
-
读取内存的值
MOV ECX,0x13FFD0 #将0x13FFD0这个地址编号,放到到ECX寄存中,此地址就是ecx的基址 #中间可能还有很多对ecx中的值的操作,我们只要找到ecx的基址,就可以跟踪ecx,最后得到下面语句中ecx究竟是什么 MOV EAX,DWORD PTR DS:[ECX] #将ECX寄存中存储的0x13FFD0这个地址中的值取出来放到EAX里
-
向内存中写入数据
MOV EDX,0x13FFD8 #将0x13FFD8存入EDX中 MOV DWORD PTR DS:[EDX],0x87654321 -
获取内存编号
LEA EAX,DWORD PTR DS:[EDX]
3.寻址方式三[reg+立即数]
-
通过[reg+立即数]
-
读取内存的值
MOV ECX,0x13FFD0 MOV EAX,DWORD PTR DS:[ECX+4] #将地址编号为0x13FFD0+0x000004中的值取出存到EAX中 -
向内存中写入数据
MOV EDX,0x13FFD0 MOV DWORD PTR DS:[EDX+0xC],0x87654321 -
获取内存编号
LEA EAX,DWORD PTR DS:[EDX+4]
4.寻址方式四[reg+reg*{1,2,4,8}]
-
通过[reg+reg*1或者2或者4或者8]来寻址,只能是1,2,4,8,后面学硬编码就知道了
-
读取内存的值
MOV EAX,0x13FFC4 MOV ECX,2 MOV EDX,DWORD PTR DS:[EAX+ECX*4] #将0x13FFC4+0x8后的地址编号中的值取出来存到EDX特殊情况:如果[reg+reg*{1,2,4,8}]得到的内存地址编号不是栈的表示地址,比如算出来的结果是0x0019ff7A,我们知道栈中每个地址编号之间相差4,是因为用一个首地址0x0019ff78表示了0x0019ff78到0x0019ff7B这四个内存块,一共4字节,所以0x0019ff78后面才能显示存的值为0x004010f0。实际上0x0019ff7A中存的值为0x40(一个字节),而上面的命令用的是DWORD,表示读取4字节作为整体存入edx中,所以就从0x0019ff7A后面往后取4字节,即取0x19ff7A,0x19ff7B,0x19ff7C,0x19ff7D中的值,最终结果为0xFA100040(写的时候记得从高位开始写)
-
向内存中写入数据
MOV EAX,0x13FFC4 MOV ECX,2 MOV DWORD PTR DS:[EAX+ECX*4],87654321 #将87654321这个值写入到0x13FFC4+0x8这个内存中 -
获取内存编号
LEA EAX,DWORD PTR DS:[EAX,ECX*4] #只是将EAX,ECX*4这个地址编号存入到EAX中
5.寻址方式五[reg+reg*{1,2,4,8}+立即数]
-
通过[reg + reg*1或者2或者4或者8 + 立即数 ]
-
读取内存的值
MOV EAX,0x13FFC4 MOV ECX,2 MOV EDX,DWORD PTR DS:[EAX+ECX*4+4] -
向内存中写入数据
MOV EAX,0x13FFC4 MOV ECX,2 MOV DWORD PTR DS:[EAX+ECX*4+4],87654321 -
获取内存编号
LEA EAX,DWORD PTR DS:[EAX+ECX*4+2]
三、作业
1.内存读写练习
-
每种寻址公式分别实现内存的读、写和取内存地址
-
寻址公式一:[立即数]
mov eax,dword ptr ss:[0x0019ff74] #读取内存 mov dword ptr ss:[0x0019ff74],0xAAAAAAAA #写入内存 lea eax,dword ptr ss:[0x0019ff74] #取内存地址 -
寻址公式二:[reg]
mov eax,dword ptr ss:[esp] mov dword ptr ss:[esp],0xBBBBBBBB lea eax,dword ptr ss:[esp]注意mov指令两个参数不能同时为寄存器
-
寻址公式三:[reg + 立即数]
mov eax,dword ptr ss:[esp+4] mov dword ptr ss:[ebp-8],edx #将edx中的值存入到[ebp-8]内存 lea eax,dword ptr ss:[esp+8] -
寻址公式四:[reg + reg * {1,2,4,8}]
mov eax,2 lea ecx,dword ptr ss:[ebp] #现在ecx中存的值即为栈底地址编号0x19ff80 lea ebx,dword ptr ss:[esp] #现在ebx中存的值即为栈顶地址编号0x19ff74 ---------------------------------- #mov edx,dword ptr ds:[ecx-eax*1] 不能是减法!!! mov edx,dword ptr ds:[ebx+eax*1] #将0x19ff76地址编号以及往高位的后三位地址编号组合起来的数存入 edx中 mov edx,dword ptr ds:[ebx+eax*2] #将0x19ff78地址中的值复制一份存入edx中 ---------------------------------- mov dword ptr ds:[esp+eax*2],ecx lea eax,dword ptr ds:[esp+eax*4] -
寻址公式五:[reg + reg * {1,2,4,8} + 立即数]
mov eax,1 mov ebx,dword ptr ss:[esp+eax*4+0x2] #fa100019 mov dword ptr ss:[esp+eax*4+0x2],edx lea eax,dword ptr ss:[esp+eax*4+0x2]
-
本文详细讲解了CPU如何通过五种寻址方式(立即数、寄存器、寄存器+立即数、寄存器+寄存器*、寄存器+寄存器*+立即数)来访问内存,包括MOV、MOVDWORD等指令实例,并提供了内存读写和地址获取的练习题。
783

被折叠的 条评论
为什么被折叠?



