80X86汇编相关

80X86汇编相关
32位CPU的通用寄存器
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
16位ax寄存器即为32位寄存器eax的后半部分,8位AL则位32位eax的俩位
0000 ffff EAX
ffff--------AX
ffff中的低八位是AL,高八位是AH

cpu寄存器空间有限,程序运行时的数据存储,主要在内存中

程序所使用的内存,与系统内存并不一致,而是在程序使用过程中,通过映射的方式来使用系统内存。通常一个pc进程创建时就会分配到4g的内存空间,使用这些内存时需要对每块内存进行一个标识,这个独立标识就是我们所说的内存地址。
这里有个问题,程序内存是一个虚拟分配出的空间,使用这部分内存时,我们按照使用系统内存的规范去使用,但是进程却只能操作到自己的虚拟内存,而系统内存则需要通过映射去实现,那在进程使用过程中所选用的内存地址和系统内存地址之间,会存在一定量的偏差(进程内存采用系统内存的使用方式,也是为了减少这种偏差的不确定性),这个偏差就是我们日常使用过程中所说的地址偏移。

内存地址为一个32位的长度的表示,换算成16进制,长度位8为

内存地址最大值为FFFF FFFF ->这是由进程所获得的最大内存所决定的,每个进程享用4g内存
4g = 41024102410248bit
每个内存空间32位长度,8bit
41024102410248/8 = 102410241024*4 = 0000 0000 -->FFFF FFFF 共计 4294967296个地址

读取内存的值:
MOV reg,[0x13ffd0]
往内存中写入数据
MOV DWORD PTR DS:[0x13ffd0],12345678

===========================================================================================================================================
数据的存储模式
大端模式与小端模式
数据存储到内存中,经常会出现一个内存块存不下对应数据的情况,那么就需要对数据进行拆分存储,按字节拆分后,则有俩种存储选择,即数据高位,存储到内存低位,数据低位,存储到内存高位,即是大端存储。
对应的,数据高位,存储到内存高位,数据低位,存储到内存低位的模式位小端存储模式。
直观的表述一下,即大端存储模式位从左往右拆分数据存储,小端模式是从右往左拆分数据存储。
ARM通常采用大端存储:0018FF8C->11223344->8C为内存低位,44为数据低位,故而对应关系为:8C:11,8D:22,8E:33,8F:44=0018FF8C-0018FF8F:11 22 33 44
X86通常采用小端存储:0018FF8C->11223344->小端存储相反,8C->44,8D->33,8E->22,8F->11
=0018FF8C-0018FF8F:44 33 22 11

===========================================================================================================================================
指令
MOV ADD SUB AND OR XOR NOT(单操作数)
MOVS:移动数据 内存-内存
补充:EDI,ESI串copy指令专用寄存器,ECX计数寄存器
MOVSD,MOVSW,MOVSB----MOVS DWORD PTR DS:[EDI],DWORD PTR DS :[ESI] 将ESI指向的内存中的数据存到EDI指向的内存中,存取数据长度必须一致
STOSD,STOSW,STOSB----STOS BYTE PTR DS:[EDI] 将8位宽度的AL寄存器的值存储到EDI指向的位置
REP指令:按ECX中的数值来重复执行后续指令(MOVSD或STOSD等等)

============================================================================================================================================
堆栈
所谓堆栈,就是一块特殊用途的内存,由操作系统在程序启动的时候,分配好的空间,供程序执行时使用。
程序执行过程中,所使用到的所有数据,必定会在堆栈中有所使用。
ESP=栈指针寄存器,EAX=返回值存放寄存 器
PUSH与POP
PUSH 向堆栈中压入数据
POP 释放堆栈中的数据

寄存器EIP 》》》
EIP与通用寄存器不是一回事,EIP中存储的内容位程序执行到下一步将要使用的地址
由于EIP不是通用寄存器,使用mov指令,无法直接修改其值,这里就要使用jmp来达到目的
call指令,同样可以修改EIP的值,并将call指令指向的地址的下一步的值,存到栈顶
RET指令,将栈顶指针存储的地址存到EIP中,栈顶指针减4

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数
指令的集合,为了完成某个重复功能而设计使用
例如:向寄存器中赋值

调用函数的俩种方式:JMP&CALL,因为程序执行常常需要返回到执行原处,故而函数调用多用call指令。(CALL相较于JMP,可以用RET回到调用处)

堆栈存参
当函数中需要用得参数较多,可以将参数放到堆栈中,指令执行时,通过调用堆栈来达到较多参数下的函数逻辑。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
何谓堆栈平衡
函数调用或程序执行时,在ret调用前后,堆栈指向的数值应该保持一致,这就是所谓的堆栈平衡。
堆栈平衡是确保程序按设计执行的准则,若程序不能保证堆栈平衡,则执行线容易出错。
如果函数或程序调用时,用到了堆栈来传参,那么在调用结束后,需要释放掉堆栈空间,否则不断积累的堆栈垃圾数据,会造成堆栈溢出甚至数据紊乱。

—————————————————————————————————————————————————————————————————————————————————————————————————————
ESP寻址与EBP寻址
栈顶指针寻址:优点是灵活使用,缺点是计算频繁
栈底指针寻址:由于栈底指针数值固定,计算出错程度低于esp

———————————————————————————————————————————————————————————————————————————————————————————————————————
标志寄存器EFL

31 ……22……15	14	13 12	11	10	9	8	7	6	5	4	3	2	1	0
0... ... ..null....0	null	nullnull	OF	DF	IF	TF	SF	ZF	0	AF	0	PF	1	CF

如:
OF为溢出标志
IF中断使能标志等

CF位:用来判断无符号数运算的溢出状态,0为无溢出,1为有溢出
OF为:有符号数的运算结果是否溢出,0为无溢出,1为有溢出
PF位:奇偶校验位,包含偶数为1,否则为0(只计算最后一个字节)
ZF位:运算结果为0,值置为1,反之为0。(常与CMP,TEST等指令一起使用)
SF位:运算结果是正数还是负数:0为正数,1为负数
DF位:方向控制串指令,DF为0,内存空间占用后地址递增使用,DF为1则递减。STD以及CLD指令用于控制DF标志:STD->1,CLD->0  
posted @ 2021-12-23 14:37  DasNI  阅读(70)  评论(0)    收藏  举报