一、通用寄存器
计算机可以将数据存在:CPU、内存、硬盘
寄存器就是CPU中用来存储数据的地方
8个32位通用寄存器
EAX:返回值存放
EBX:寻址存放基地址
ECX:计数器
EDX:余数存放
ESP、EBP:栈顶指针、EBP指向系统栈最上面一个栈帧的底部
ESI、EDI:源索引寄存器,指向源串 / 目标串
特殊
EIP:CPU即将执行指令地址,无法作为他用
寄存器之间的关系
寄存器的修改操作
mov指令传送赋值
mov 目标地址,源地址
二、内存与内存地址
内存
虽然CPU可以存储数据,但是有限,所以需要更大的容器,那么就是内存。
每个程序都有自己的独立的4GB的空间。(这里的4GB的空间,只是虚拟的)
4GB怎么得来:
1、比方我们的计算器是32位,那么存储最大就是FFFFFFFF,0也是一个数,所以FFFFFFFF+1=100000000个内存单元
2、一个内存单元存储8位,100000000*8=800000000(十六进制,转为十进制) = 34359738368
3、得出最终能存储的大小,34359738368 / 8(bit) = 4294967296(byte)
4、4294967296 / 1024 = 4194304(KB) / 1024 = 4096(MB) / 1024 ≈ 4(GB)
1Byte = 8位
1KB = 1024Byte
1MB = 1024KB
1GB = 1024MB
位 Bit 只存一位二进制
字节 Byte 可存储八位二进制0~FF
字 Word 可存储十六位二进制0~FFFF
双字 Dword 可存储三十二位二进制0~FFFFFFFF
内存地址
三、寻址方式
直接寻址
间接寻址
这种,地址需要通过计算才能知道的,属于间接寻址方式,无法立马看出地址的。
mov eax,[reg] 寄存器间接寻址
mov eax,[reg+立即数]
mov eax,[reg+reg*立即数] 乘的立即数是{1、2、4、8}之间的其中一个,为其他数值会报错
mov eax,[reg+reg*立即数+立即数]
四、常用汇编指令
1、MOV 数据传送指令
注:r = 通用寄存器,m = 内存,imm = 立即数,r8 = 8位通用寄存器,m8/imm8同理
2、ADD 加法指令
注:r = 通用寄存器,m = 内存,imm = 立即数,r8 = 8位通用寄存器,m8/imm8同理
3、SUB 减法指令
注:r = 通用寄存器,m = 内存,imm = 立即数,r8 = 8位通用寄存器,m8/imm8同理
4、AND 与运算
注:r = 通用寄存器,m = 内存,imm = 立即数,r8 = 8位通用寄存器,m8/imm8同理。
5、OR 或运算
注:r = 通用寄存器,m = 内存,imm = 立即数,r8 = 8位通用寄存器,m8/imm8同理。
6、XOR 异或运算
注:r = 通用寄存器,m = 内存,imm = 立即数,r8 = 8位通用寄存器,m8/imm8同理。
7、NOT 非运算
注:r = 通用寄存器,m = 内存,imm = 立即数,r8 = 8位通用寄存器,m8/imm8同理。
五、堆栈
堆栈
堆栈:一块特殊的内存,软件启动的时候,是系统分配给程序使用的,存储临时数据等
和普通内存不一样的地方在于,一个是人工申请,一个是系统分配。
mov dword ptr ds:[0x19FF6C],0x66666666
将数据储存到0019FFc
执行完毕,ESP不变,数据存储完成,因为ESP指向的还是源地址,所以如果有下一条存储指令,就会覆盖存储的那个数据,所以要sub esp,0x4,让esp-4,指向我们赋值的地址
—————————————————————————————
PUSH:压栈,将数据压入堆栈,并且修改esp指向
PUSH 寄存器
PUSH 立即数
PUSH 内存
现在eax的值已经被压入堆栈,我想重新取回到eax里,
POP:出栈,将数据弹出堆栈,并且修改esp
POP 寄存器
POP 内存
六、修改EIP
修改通用寄存器可以用mov指令,但是无法修改eip。因为,EIP存放的是CPU下一次要执行的指令的地址,但是有三个指令,可以修改掉他,分别是JMP、CALL、RET。
也就是,修改了CPU下一次执行的指令地址。
JMP指令
无条件跳转。修改EIP,且只影响EIP。内存/立即数/寄存器,都可以操作
CALL指令
如果要执行CALL指令,要用F7,不要平时的执行方法,用F8去执行,会影响栈顶地址 / ESP / EIP,因为CALL要记录一个返回的地址(也就是CALL的下一行)
按F8就会直接运行到CALL指令的下一行,把CALL当一行指令来执行,F7就会进入CALL,执行CALL内的指令
前
后
CALL指令修改了EIP
向堆栈存储了一个值(CALL指令下一行的地址)
ESP的值发生了改变
RET指令
有CALL就有RET。
把CALL压入堆栈的值,再返回给EIP,然后栈顶+4。
修改了ESP,因为返回地址后,esp+4,平衡了堆栈
修改了EIP,eip又指向了call函数的下一行的地址