学习笔记分享之汇编---3. 堆栈&标志寄存器

前言:
  此文章收录在本人的《学习笔记分享》分类中,此分类记录本人的学习心得体会,现所有分享出来但愿和你们共同交流学习成长。附上分类连接:
  https://www.cnblogs.com/tibbors/category/1729804.htmlhtml

学习内容:堆栈

image-20200321212731984

  • 堆栈的优势:临时存储大量数据,便于查找
  • 堆栈中越往顶部地址编号越小
  • 压栈出栈变的都是栈顶

堆栈的操做分解:学习

前提操做:
	MOV EBX,13FFDC	//BASE
	MOV EDX,13FFDC	//TOP


操做一:压入数据
	法一:
	MOV DWORD PTR DS:[EDX-4],0xAAAAAAAA		//先压入数据
	SUB EDX,4								//再上移地址(寄存器)

	法二:
	SUB EDX,4								//先上移地址(寄存器)
	MOV DWORD PTR DS:[EDX],0xBBBBBBBB		//再压入数据
	
	法三:
	MOV DWORD PTR DS:[EDX-4],0xDDDDDDDD		//先压入数据
	LEA EDX,DWORD PTR DS:[EDX-4]			//再经过LEA指令上移地址(寄存器)
	
	法四:
	LEA EDX,DWORD PTR DS:[EDX-4]			//先经过LEA指令上移地址(寄存器)
	MOV DWORD PTR DS:[EDX],0xEEEEEEEE		//再压入数据


操做二:读取某个数据
	法一:
	//经过[BASE+偏移量]读取
	MOV ESI,DWORD PTR DS:[EBX-4]

	法二:
	//经过[TOP+偏移量]读取
	MOV EDI,DWORD PTR DS:[EDX+4]


操做三:弹出数据
	法一:
	MOV ECX,DWORD PTR DS:[EDX]				//先弹出数据(保存到其余存储空间)
	LEA EDX,DWORD PTR DS:[EDX+4]			//再下移地址(寄存器)

	法二:
	MOV ESI,DWORD PTR DS:[EDX]				//先弹出数据(保存到其余存储空间)
	ADD EDX,4								//再下移地址(寄存器)
	
	法三:
	LEA EDX,DWORD PTR DS:[EDX+4]			//先下移地址(寄存器)
	MOV EDI,DWORD PTR DS:[EDX-4]			//再弹出(下移前地址)数据(保存到其余存储空间)

堆栈的专用操做:操作系统

  • 操做系统默认把ESP当栈底,EBP当栈顶
  • PUSH(压栈) = 操做一
  • POP(出栈) = 操做三



学习内容:标志寄存器(EFLAGS)

image-20200320085359270

  1. 进位标志寄存器CF(Carry Flag)(针对无符号数):3d

    进位标志CF用于反映无符号数加减运算中最高位是否有进位。code

    • 有:1htm

    • 无:0blog

    e.g.get

    MOV AL,0xEFit

    ADD AL,2io

    image-20200320104645403

    MOV AL,0xFE

    ADD AL,2

    image-20200320110440794

  2. 溢出标志寄存器OF(Overflow Flag)(针对有符号数):

    溢出标志OF用于反映有符号数加减运算所得结果是否溢出。

    (若是运算结果超过当前运算位数所能表示的范围,则称为溢出)

    • 溢出:1
    • 未溢出:0
    O位计算过程:
    
    符号位有进位:1;无进位:0
    
    最高有效数值位向符号位有进位:1;无进位:0
    
    对 符号位有无进位 和 最高有效位有无进位 进行异或:所得值即为OF位的值

补充(CF与OF):
在有符号的运算中,有以下的规律:

  • 正 + 正 = 正 若是结果是负数,则说明有溢出

  • 负 + 负 = 负 若是结果是正数,则说明有溢出

  • 正 + 负 永远都不会有溢出

    可根据右图理解无符号数和有符号数不一样状况: image-20200320113441839

    也可根据此图找出如下四种状况:

    无符号、有符号都不溢出 无符号溢出、有符号不溢出
    MOV AL,8 ADD AL,8 MOV AL,FF ADD AL,2
    无符号不溢出、有符号溢出 无符号、有符号都溢出
    MOV AL,7F ADD AL,2 MOV AL,FE ADD AL,80
  1. 符号标志SF(Sign Flag):

    符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。

    e.g.

    细心观察S位变化

    MOV EAX,0x0A7F

    image-20200320160438403

    ADD EAX,2

    3.2

    SUB EAX,2

    image-20200320160839680

    ADD AL,2

    image-20200320161022523

    SUB AL,2

    image-20200320161110448

    能够发现:S位只看参与运算的宽度的符号位的值是1仍是0
    		一样的结果,用EAX将32位所有参与运算时不论怎样,S值都为0,由于最高位为0
    		而用AL只运算后八位时,S值被置为1,由于此时参与运算部分的最高位为1
  2. 辅助进位标志AF(Auxiliary Carry Flag):

    在发生下列状况时,辅助进位标志AF的值被置为1,不然被置为0:

    (粗略理解:只要发生除最高位之外的进位或借位就会被置为1)

    ①在字操做时,低字节向高字节进位或借位

    ②在字节操做时,低4位向高4位进位或借位

    e.g.

    MOV EAX,55EEFFFF

    ADD EAX,2

    image-20200320123424054

    MOV AX,5EFE

    ADD AX,2

    image-20200320123441392

    MOV AL,4E

    ADD AL,2

    image-20200320123453962

  3. 奇偶标志PF(Parity Flag):

    奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。

    • 偶数个1:1
    • 奇数个1:0

    e.g.

    MOV EAX,AEF

    ADD EAX,2

    image-20200320154450541

    从上图能够看出,虽然0x0B00(即0000 1011 0000 0000)有奇数个1,P位应该为0

    所以,对于P位寄存器,只看最低有效字节(低8位(十六进制的后两位))(无论是多少位寄存器)
  4. 零标志ZF(Zero Flag):

    零标志ZF用来反映运算结果是否为0。

    • 为0:1
    • 不为0

    e.g.
    XOR EAX,EAX     //功能为清零
    xor
    注意:
     MOV EAX,0和XOR EAX,EAX虽然结果同样,可是意义不同,由于MOV不是运算符,而XOR是,所以若用MOV,EFLAGS寄存器就不会有变化

  5. 方向标志DF(Direction Flag):

    方向标志DF用来决定 ① 执行MOVS指令时[ESI]和[EDI]中存储的地址 ② 执行STOS指令时的 加/减

    • 为0:加
    • 为1:减
相关文章
相关标签/搜索