程序在计算的时候,需要用到数据,那么这些数据都需要地方来存储,寄存器和内存就是用来存储数据的容器
计算机用来存储数据的有CPU中的寄存器和内存条中的内存。CPU中的寄存器虽然容量小,但是可以高速进行读写;内存虽然存取速度相对较慢一些,但是可以存储大量的内容
我们今天学习的是CPU中常用到的数据宽度为32位的容器,称为32位通用寄存器
32位通用寄存器:从上到下挨着顺序记,编号也记住后面硬编码要用
什么是32位,就是下面的寄存器可以用32位来存储数据,通俗来说就是一个寄存器可以用32个0或者1来存数据。虽然当初设计时不同的寄存器建议存什么东西做什么运算,但是实际上自己想怎么用寄存器就怎么用,知道有哪些寄存器即可
| 寄存器 | 编号 | 存储数据的范围 |
|---|---|---|
| EAX | 0 | 0 - 0xFFFFFFFF |
| ECX | 1 | 0 - 0xFFFFFFFF |
| EDX | 2 | 0 - 0xFFFFFFFF |
| EBX | 3 | 0 - 0xFFFFFFFF |
| ESP | 4 | 0 - 0xFFFFFFFF |
| EBP | 5 | 0 - 0xFFFFFFFF |
| ESI | 6 | 0 - 0xFFFFFFFF |
| EDI | 7 | 0 - 0xFFFFFFFF |
寄存器的使用:
MOV EAX,12345678 #MOV是汇编指令,EAX是寄存器,后面的数叫立即数,此指令的作用就是将立即数存在EAX中 ADD EAX,1 #将1与EAX中已经存储的数做加法运算,结果再存储在EAX中 MOV ECX,2 ADD EAX,ECX #将EAX与ECX中的值相加,将结果再放入EAX中 SUB EAX,3 #用EAX中的值-3,再将结果放入EAX中二、作业 1.使用OD查看寄存器并且使用MOV指令修改寄存器中值
使用OD打开一个EXE程序,并找到寄存器窗口
单步执行程序(F8)
因为一个可执行程序打开会发现它停在了一个地址处,至于为什么后面学汇编详解,这里我们只需知道EIP寄存器中的存的值是什么,此时程序就执行到哪了,反过来说也可以。那么我们如果按F8,则会从现在停在的地址,单步往后执行一条指令
记住这个8个通用寄存器的名称,按照顺序:EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
如何自己写汇编指令,在左上角的框框里,双击程序正在执行的地址那一行的指令,可以新添加指令或者修改指令,最后按Assemble添加或修改成功。添加或修改后,这条指令会作为程序即将执行的指令,当按f8时,程序会执行你新添加的指令,添加多条,会依次向下覆盖,程序执行处在第一条你新添加的指令地址处
使用MOV指令修改8个寄存器的值
注意因为寄存器是32位的,所以如果地址数值大于了32位,即会从低位取32位,多余的位将被丢弃
除此之外还可以直接双击寄存器的值,直接修改即可
三、通用寄存器
寄存器不光只有32位寄存器,还有8位、16位、和64位寄存器。这些统称为通用寄存器
| 寄存器 | 编号(二进制) | 编号(十进制) | ||
|---|---|---|---|---|
| 32位 | 16位 | 8位 | ||
| EAX | AX | AL | 000 | 0 |
| ECX | CX | CL | 001 | 1 |
| EDX | DX | DL | 010 | 2 |
| EBX | BX | BL | 011 | 3 |
| ESP | SP | AH | 100 | 4 |
| EBP | BP | CH | 101 | 5 |
| ESI | SI | DH | 110 | 6 |
| EDI | DI | BH | 111 | 7 |
我们根据需要的大小来挑选合适宽度的寄存器,只要能够存下需使用的数据即可
16位寄存器在32位寄存器中,16位寄存器是32位寄存器的一部分。可以这么理解,32位寄存器的前半部分为16位寄存器;前四个16位寄存器(ax,cx,dx,bx)又可以分为两个8位寄存器
可以用下列指令验证:
MOV EAX,0xAAAAAAAA MOV AX,0xBBBB MOV AH,0xCC MOV AL,0xDD
未执行前,eax寄存器中的值为:0x0019ffcc
执行第一条指令MOV EAX,0xAAAAAAAA,则eax中存储的值变为0xAAAAAAAA
执行第二条指令MOV AX,0xBBBB,则eax中第0位到31位变为BBBB,则最后结果为0xAAAABBBB
执行第三条指令MOV AH,0xCC,则eax第8位到15位变为CC,最后结果为0xAAAACCBB
执行到第四条指令MOV AL,0xDD,则eax第0位到第7位变为DD,最后结果为0xAAAACCDD
四、汇编指令 1.MOV
格式:mov eax,0xAAAAAAAA指令中mov叫操作码,eax叫目标操作数,0xAAAAAAAA叫源操作数。
作用:mov指令就是将源操作数复制一份放到目标操作数!
要求:
源操作数宽度必须和目标操作数宽度一致
即eax为32位寄存器,那么只能将32位的源操作数存入eax中,如果少了会在高位自动补零,如果多了,则会从低位取32位,后面多余部分会被丢弃
源操作数可以是立即数、通用寄存器、段寄存器(后面会讲)、或者内存单元
目标操作数可以是通用寄存器、段寄存器或者内存单元
源操作数和目标操作数不能同时为内存单元(很多汇编程序都不允许,但有特例)
语法:
r 通用寄存器;m 代表内存;imm 代表立即数;r8 代表8位通用寄存器;m8 代表8位内存;imm8 代表8位立即数
MOV r8/m8,r8 #可以将8位通用寄存器中的值存入8位通用寄存器或者8位内存中 MOV r16/m16,r16 MOV r32/m32,r32 MOV r8,r8/m8 #可以将8位通用寄存器或者8位内存中的值存入8位寄存器中 MOV r16,r16/m16 MOV r32,r32/m32 MOV r8,imm8 #将一个8位的立即数存入8位通用寄存器中 MOV r16,imm16 MOV r32,imm322.ADD
格式:与mov类似,有操作码,目标操作数和源操作数构成
作用:将目标操作数与源操作数相加,将结果存入到目标操作数
要求:
源操作数宽度可以和目标操作数宽度不一致!()??????是只能源操作数为立即数时可以不一样?还是都可
源操作数可以是立即数、通用寄存器、段寄存器(后面会讲)、或者内存单元
目标操作数可以是通用寄存器、段寄存器或者内存单元
源操作数和目标操作数不能同时为内存单元
语法:
ADD r8/m8,imm8 ADD r16/m16,imm16 ADD r32/m32,imm32 ADD r16/m16,imm8 #源操作数与目标操作数可以不一致!! ADD r32/m32,imm8 ADD r8/m8,r8 ADD r16/m16,r16 ADD r32/m32,r32 ADD r8,r8/m8 ADD r16,r16/m16 ADD r32,r32/m323.SUB
格式:操作码 目标操作数,源操作数
作用:将目标操作数减源操作数的结果存入目标操作数
要求:
源操作数宽度可以和目标操作数宽度不一致!?????????????
源操作数和目标操作数不能同时为内存单元
语法:
SUB r8/m8,imm8 #8,16,32位都可以 SUB r8/m32,imm32 #源操作数与目标操作数宽度可以不一致 SUB r32/m32,r32 SUB r32,r32/m324.AND
格式:操作码 目标操作数,源操作数
作用:目标操作数与源操作数做与逻辑运算,将结果存入目标操作数
要求:
源操作数和目标操作数不能同时为内存单元源操作数宽度可以和目标操作数宽度不一致!
语法:
AND r8/m8, imm8 AND r16/m16,imm16 AND r32/m32,imm32 AND r16/m16, imm8 AND r32/m32, imm8 AND r8/m8, r8 AND r16/m16, r16 AND r32/m32, r32 AND r8, r8/m8 AND r16, r16/m16 AND r32, r32/m325.OR
作用:目标操作数与源操作数做或逻辑运算,将结果存入目标操作数
语法:
OR r8/m8, imm8 OR r16/m16,imm16 OR r32/m32,imm32 OR r16/m16, imm8 OR r32/m32, imm8 OR r8/m8, r8 OR r16/m16, r16 OR r32/m32, r32 OR r8, r8/m8 OR r16, r16/m16 OR r32, r32/m326.XOR
作用:目标操作数与源操作数做亦或逻辑运算,将结果存入目标操作数(后面加密解密时经常使用)
语法:
XOR r8/m8, imm8 XOR r16/m16,imm16 XOR r32/m32,imm32 XOR r16/m16, imm8 XOR r32/m32, imm8 XOR r8/m8, r8 XOR r16/m16, r16 XOR r32/m32, r32 XOR r8, r8/m8 XOR r16, r16/m16 XOR r32, r32/m327.NOT
格式:操作码 操作数(只有一个操作数)
作用:操作数做非逻辑运算,将结果存入操作数中
语法:
NOT r8/m8 NOT r16/m16 NOT r32/m32



