80x86汇编3-寄存器与内存

寄存器是什么?

通俗来讲,寄存是CPU内部的一块高速存储空间,速度远大于内存
32位通用寄存器

寄存器 主要用途 编号 存储数据的范围
EAX 累加器 0 0-0xFFFFFFFF
ECX 计数器 1 0-0xFFFFFFFF
EDX I/o指针 2 0-0xFFFFFFFF
EBX DS段的数据指针 3 0-0xFFFFFFFF
ESP 堆栈指针 4 0-0xFFFFFFFF
EBP SS段的数据指针 5 0-0xFFFFFFFF
ESI 字符串操作源指针 6 0-0xFFFFFFFF
EDI 字符串操作的目标指针 7 0-0xFFFFFFFF

在这里插入图片描述

在这里插入图片描述
32位 通用寄存器由8位寄存器开始演变,一个32位寄存器包含了16位和8位
EAX其实是AX16位通用寄存器扩展而来,同理RAX64位通用寄存器也是由32位通用寄存器扩展而来!

基础汇编指令

  1. MOV(移动)
MOV EAX,AAAAAAAA
MOV AX,1111
MOV ECX,33
MOV CX,3
...

MOV的语法:
在这里插入图片描述
MOV 目标操作数,源操作数
作用:拷贝源操作数到目标操作数
·1、源操作数可以是立即数、通用寄存器、段寄存器、或者内存单元.
·2、目标操作数可以是通用寄存器、段寄存器或者内存单元.
·3、操作数的宽度必须一样.
·4、源操作数和目标操作数不能同时为内存单元.

不是很了解不要紧,只需要记住一般情况下使用

MOV EAX,0x11111111     //把一个4字节的数字放到32/16/8位通用寄存器里
MOV EAX,[0x401050]     //把内存中的数据放到32/16/8位通用寄存器里

·
2. ADD(加法)
在这里插入图片描述
加法指令不同于移动指令(MOV),加法指令可以把一个数据累加到内存中

ADD EAX,12345678         //把EAX寄存器里面存储的内容与12345678相加,然后存到EAX,例如EAX是1,ADD加完以后EAX就是12345679
ADD [0x401050],12345678  //把数字和内存中的数据相加然后存回内存,同理EAX
!!ADD不可以两个数字相加,数字在汇编中被称为立即数,数字本身并没有存储内容的功能

  1. SUB(相减)

  1. rep指令(大多数用于填充堆栈)
lea edi,[ebp-40]
mov ecx,0x10
mov eax,0xcccccccc
rep stos dword ptr[edi]

结论:rep会读取edi的地址,根据df标志位判断方向,根据ecx判断剩余次数,根据eax得到需要填充的值,再根据dword的宽度填充堆栈内存[edi],默认df=1,然后ecx-1,edi-dword


  1. movzx和movsx

MOVSX,MOVZX 与MOV指令区别:
1、MOVSX,MOVZX的操作数B所占空间必须小于操作数A.
2、MOV指令是原值传送,不会改动。而MOVSX与MOVZX有可能会改动
MOVSX与MOVZX的区别:
1、MOVSX将用操作数B的符号位扩展填充操作数A的余下空间,如果是负数则符号位为1,如果是正数则和MOVZX功能相同
2、MOVZX将用0来扩展填充操作数A的余下空间

在这里插入图片描述

	__asm
	{
		mov bl,80
		movzx ax,bl
	}//0x0080

	__asm
	{
		mov bl, 80
		movsx ax, bl
	}//0xFF80

内存

内存是我们最常用是存储数据的载体!它位于我们计算机的主板,但是主板上的内存条并不是我们实际使用的内存空间,我们使用的内存空间都是由操作系统分配和回收的虚拟内存
寄存器与内存的区别:

  1. 寄存器位于CPU内部,执行速度快,但比较贵
  2. 内存速度相对较慢,但成本较低,所以可以做的很大
  3. 寄存器和内存没有本质区别,都是用于存储数据的容器,都是定宽的
  4. 寄存器常用的有8个:EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI
  5. 计算机中的几个常用计量单位:BYTE WORD DWORD

BYTE 字节 = 8(BIT)
WORD 字 = 16(BIT)
DWORD 双字 = 32(BIT)
1KB = 1024 BYTE
1MB = 1024 KB
1MB = 1024 KB

  1. 内存的数量特别庞大,无法每个内存单元都起一个名字,所以用编号来代替,我们称计算机CPU是32位或者64位,主要指的就是内存编号的宽度,而不是寄存器的宽度.有很多书上说之所以叫32位计算机是因为寄存器的宽度是32位,是不准确的,因为还有很多寄存器是大于32位的
    计算机内存的每一个字节会有一个编号(即内存编号的单位是字节)
0x00000000 0x00000001 0x00000002 0x00000003 0x00000004 0x00000005
00000000 00000001 00000002 00000003 00000004 00000005

32位计算机的编号最大是32位,也就是32个1 换成16进制为FFFFFFFF,也就是说,32位计算机内存寻址的最大范围是FFFFFFFF+1
内存的单位是字节,那内存中能存储的信息最多为:FFFFFFFF+1 字节 即4G,这也是为什么我们在一个XP的系统上面如果物理内存超过4G是没有意义的原因

内存的格式

在这里插入图片描述
1、每个内存单元的宽度为8(8个16进制数,4字节,32个2进制数)
2、[编号]称为地址
3、地址的作用:当我们想从内存中读取数据或者想向内存中写入数据,首先应该找到要读、写的位置。就像写信要写地址一样。

从指定的内存中读写数据:

mov dword ptr ds:[0x0012FF34],0x12345678
mov eax,dword ptr ds:[0x0012FF34]
dword :要读/写多少  此时是4字节   byte == 1字节  word == 2字节
ptr: Point 代表后面是一个指针 (指针的意思就是里面存的不是普通的值,而是个地址)
ds:段寄存器
0x0012FF34:内存编号,必须是32位的  前面0可以省略
注意:地址编号不要随便写,因为内存是有保护的,并不是所有的内存都可以直接读写(需要特别处理)

为什么需要dword?因为寄存器是定宽的,4字节的,如果是内存的话,可以存很多数据,如果不告诉系统你要操作是数据有多宽,就会出问题

汇编寻址公式:
.

  • 立即数
读取内存的值:
MOV EAX,DWORD PTR DS:[0x13FFC4]
MOV EAX,DWORD PTR DS:[0x13FFC8]

向内存中写入数据:
MOV DWORD PTR DS:[0x13FFC4],eax
MOV DWORD PTR DS:[0x13FFC8],ebx

获取内存编号:
LEA EAX,DWORD PTR DS:[0X13FFC4]
LEA EAX,DWORD PTR DS:[ESP+8]

.

  • REG(通用寄存器)
读取内存的值:
MOV ECX,0x13FFD0
MOV EAX,DWORD PTR DS:[ECX]

向内存中写入数据:
MOV EDX,0x13FFD8
MOV DWORD PTR DS:[EDX],0x87654321

获取内存编号:
LEA  EAX,DWORD PTR DS:[EDX]
MOV EAX,DWORD PTR DS:[EDX]

.

  • REG(通用寄存器)+立即数
读取内存的值:
MOV ECX,0x13FFD0
MOV EAX,DWORD PTR DS:[ECX+4]

向内存中写入数据:
MOV EDX,0x13FFD8
MOV DWORD PTR DS:[EDX+0xC],0x87654321

获取内存编号:
LEA  EAX,DWORD PTR DS:[EDX+4]
MOV EAX,DWORD PTR DS:[EDX+4]

.

  • REG(通用寄存器)+REG*{1,2,4,8}
读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*4]

向内存中写入数据:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4],87654321

获取内存编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4]

.

  • REG(通用寄存器)+REG*{1,2,4,8}+立即数
读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*4+4]

向内存中写入数据:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4+4],87654321

获取内存编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4+4]

猜你喜欢

转载自blog.csdn.net/qq_35425243/article/details/82759152
今日推荐