寄存器是在内存中的
32位通用寄存器
EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
EIP是存储下次cpu下次要执行的指令,不能用作他用,所以不能是通用寄存器
1.立即数到寄存器
2.寄存器到寄存器
汇编其实本质就是寄存器和寄存器或者寄存器和内存之间数据的来回流动
执行一下F8
可以看到1这个立即数存放在这两个寄存器去了,也可以把寄存器的值存放在寄存器里面
MOV EDX,EAX
32位的:EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
16位的:AX,CX,DX,BX,SP,BP,SI,DI
8位的:AL,CL,DL,BL,AH,CH,DH,BH
只有EAX,ECX,EDX,EBX有8位的,ESP,EBP,ESI,EDI没有八位的
比如EAX等于FFFF0201,02就是AH,01就是AL
比如我们先把EAX设置为-1(FFFFFFFF)
我们在执行一下
MOV AX,1
现在EAX为FFFF0001,所以说其实一个寄存器我们你可以按照不同的段使用它,其实我们想用16位的寄存器其实就是把原来的一半给他了
现在我们想用8位的寄存器,把EAX设置为-1
MOV AL,2执行一下,EAX为FFFFFF02,可以看到只变了8位一个字节
如果我们y要存储的数据很多就单靠cpu中的寄存器是不够的,每个应用程序都会有自己的独立的4G内存空间
假如我们内存只有2G但是两个进程加起来就8G了这明显不科学,其实这里可以理解为空头支票,也就是说把这4G给你了,你可以在这里面随便用,但是随便用意为着当你某个时刻真的要用操作系统就会把你拥的内存给映射到真正的内存里面,物理内存也不是我们的所谓内存条,他们之间也存在这一个映射
内存太大没法起名字,所以只能用编号。当我们想向内存中存储数据,或者从内存中读取数据时,必须用到编号,就想写信必须要知道地址一样
这个编号又称为内存地址(32位,前面0可以省略),这个编号也叫内存地址
我们在写入内存必须告诉它我们的宽度,比如mov 内存,1 我们必须告诉把这个1写多大进去,比如我们写如一字节
mov byte ptr ds:[0049B000],1
这里的内存地址我们不能乱写,因为必须要这个程序申请过了的才能使用,这里有个小技巧,我们可以看这一块的就是申请过的
如果我们写两字节就word,四字节就dword
这里我们是立即数写到内存,现在来寄存器写到内存
可以看到寄存器EAX为0019FFCC
mov dword ptr ds:[0019FF74],eax
可以看到内存地址为0019FF74也变成了EAX的值,我们可以把立即数写入内存中,也可以把寄存器写入内存中,前提就是数据长度必须一样,如果前面是dword后面写1也是一样的,实际上1前面默认补了7个0,但是如果前面是DWORD后面是AX就不行了,但是编译器会自动调整为WORD
内存一样可以移动到寄存器
mov dword ptr ds:[0019FF74],eax
但是不能直接内存到内存
1.形式一:【立即数】
读取内存的值:
mov eax,dword ptr ds:[0x13ffc4]
向内存中写入值:
mov dowrd ptr ds:[0x13ffc4],eax
2.形式二:【reg】reg代表寄存器,可以是8个通用寄存器中的任意一个
读取内存的值
mov ecx,0x13FFD0
mov eax,dword ptr ds:[ecx]
向内存中写入数据
mov edx,0x13FFD0
mov dword ptr ds:[edx],0x87654321
比如我们可以把EAX写为0019FF74,然后再命令写为MOV DWORD PTR DS:[EAX],12345678
执行结果如图
3.形式三:【reg+立即数】
读取内存的值:
mov ecx,0x13FFD0
mov eax,dword ptr ds:[ecx+4]
向内存中写入数据:
mov edx,0x13FFD8
mov dword ptr ds:[edx+0xC],0x87654321
4.形式四【reg+reg{1,2,4,8}】
读取内存的值:
mov eax,13FFC4
mov ecx,2
mov edx,dword ptr ds:[eax+ecx4]
向内存中写入数据:
mov eax,13FFC4
mov ecx,2
mov dword ptr ds:[eax+ecx*4],87654321
5.形式五【reg+reg{1,2,4,8}+立即数】
读取内存的值:
mov eax,13FFC4
mov ecx,2
mov edx,dword ptr ds:[eax+ecx4+4]
向内存中写入数据:
mov eax,13FFC4
mov ecx,2
mov dword ptr ds:[eax+ecx*4+4],87654321
move byte ptr ds:[0x00000000],0x1A
move word ptr ds:[0x00000000],0x1A2C
move dword ptr ds:[0x00000000],0x1A2C3D4E
我们知道0x1A就是1A,但是0X1A2C是1A在上面还是2C在上面,所以这里就分为两类:
大端模式:数据高位在低位,数据低位在高位
小端模式:数据低位在低位,数据高位在高位
这里的0x1A2C就是1A在高位,2C在低位,所以按照大端模式的话就是1A在上面2C在下面,按照小端模式的话最后一个从上到下的就是:
4E->3D->2C-1A
查看内存,比如说我想看19DBC4,假如我想看一个字节就
db 19DBC4
如果我们想两个字节的来查看的话就
dw 19DBC4
如果想4个字节的来看
dd 19DBC4
但是我们自己存入内存是什么模式呢,这里来看一下
我们这里可以看到0019DBAC这里已经存放了11223344了但是我们不知道到底AC存放的是11还是44所以这里我们可以用db一个字节来看
这里就可以看到AC是44,AD是33,AE是22,AF是11,AF是内存地址最高位,然后11也是最高位,所以我们这里是小端模式的存储方式
原文:https://www.cnblogs.com/yicunyiye/p/13639002.html