12

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

 3 years ago
source link: http://www.cnblogs.com/tibbors/p/12728484.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言:

此文章收录在本人的《学习笔记分享》分类中,此分类记录本人的学习心得体会,现全部分享出来希望和大家共同交流学习成长。附上分类链接:

https://www.cnblogs.com/tibbors/category/1729804.html

学习内容:堆栈

yIjiqqB.png!web

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

堆栈的操作分解:

前提操作:
	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)

a6NFFfZ.png!web

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

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

    • 有:1

    • 无:0

    e.g.

    MOV AL,0xEF

    ADD AL,2

    nMZVJbu.png!web

    MOV AL,0xFE

    ADD AL,2

    yYFnaiJ.png!web

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

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

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

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

在有符号的运算中,有如下的规律:

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

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

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

    可根据右图理解无符号数和有符号数不同情况: image-20200320113441839.png

    也可根据此图找出以下四种情况:

    无符号、有符号都不溢出 无符号溢出、有符号不溢出 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

    FN3amq3.png!web

    ADD EAX,2

    QRJzYvQ.png!web

    SUB EAX,2

    V36bAnN.png!web

    ADD AL,2

    nmUjmuv.png!web

    SUB AL,2

    3iAremy.png!web

    可以发现: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

    iqM3qeY.png!web

    MOV AX,5EFE

    ADD AX,2

    NjUNvqb.png!web

    MOV AL,4E

    ADD AL,2

    qmMjmyR.png!web

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

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

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

    e.g.

    MOV EAX,AEF

    ADD EAX,2

    f2qEbar.png!web

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

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

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

    • 为0:1
    • 不为0
    e.g.

    XOR EAX,EAX //功能为清零

    bUnE3az.png!web

    注意:

    MOV EAX,0和XOR EAX,EAX虽然结果一样,但是意义不一样,因为MOV不是运算符,而XOR是,因此若用MOV,EFLAGS寄存器就不会有变化

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

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

    • 为0:加
    • 为1:减

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK