Win-MASM64汇编语言-标志寄存器(EFLAGS/PSW/PUSHF/POPF)

CPU内部需要一种特殊的寄存器来完成下面三个功能

1.用来存储相关指令的执行结果是否满足某些特性
2.为cpu执行相关指令提供行为依据
3.用来控制cpu的相关工作方式

能完成上面三个功能的寄存器被成为标志寄存器,标志寄存器简称flag,里面存的内容叫psw(程序状态字)

注:标志寄存器指的是一个寄存器,而不是多个寄存器的类型是标志寄存器

用来存放各种标志位,在Visual Sudio中打开标志寄存器调试界面,调试->窗口->寄存器,此时打开寄存器窗口,但是该窗口只有通用寄存器,这个时候右键,选择"标志",然后在寄存器窗口中会显示出标志寄存器的值
在这里插入图片描述

一:进位标志位CF(Carry Flag)也叫CY
用途1:计算指令(add等)产生的结果,最高有效位发生进位(加法)或者发生借位(减法),则将其置1,反之清0,注意,是最高位,比如一个int,最高位是32位,只有当第32位继续进位(溢出)的时候,CY会由0变1,在无符号整数运算中用来表示溢出,而OF是在有符号整数中表示溢出
用途2:在多倍精度运算中使用,可以将上次产生的进位或借位传递到下一次运算中

	int a = 0x80000000;
	int b = 0x80000000;
	_asm mov eax, a;
	_asm mov ebx, b;
	_asm add eax, ebx;// 在这里CY的值会由0变成1
	int a = 0x08000000;
	int b = 0x08000000;
	_asm mov eax, a;
	_asm mov ebx, b;
	_asm add eax, ebx;// 在这里CY的值依然是0不会改变,因为最高位没有进位
	int a = 0x80000000;
	int b = 0x70000000;
	_asm mov eax, a;
	_asm mov ebx, b;
	_asm sub eax, ebx;// eax减去ebx,8-7,没有借位,所以CY值一直是0
	int a = 0x70000000;
	int b = 0x80000000;
	_asm mov eax, a;
	_asm mov ebx, b;
	_asm sub eax, ebx;// eax减去ebx,7-8,有进位,所以CY由0变1

二:奇偶标志位PF(ParityFlag)也叫PE:计算指令(add等)产生的结果如果低8位有偶数个1,则PF为1,有奇数个1则为0

	int a = 0x10;//注意是低8位,如果是0x110,右数第三位那个1不算
	int b = 0x01;
	_asm mov eax, a;
	_asm mov ebx, b;
	// 调试的时候注意程序刚开始运行的时候,PE可能会保留之前的信息
	// 所以会出现刚执行程序的时候PE有时候是0有时候是1,这并不影响结果,但是容易造成误解
	_asm add eax, ebx;// 此处代码走完PE会变成1

三:辅助进位标志AF也叫AC
计算指令(add等)产生的结果如果右数第4个bit发生了进位或借位,则置1,否则置0,在BCD算数运算中中会被用到,此处初学千万注意,右数第4个bit,指的是2进制,像0x1111这不叫右数4个bit,这叫右数16个bit了(通俗的说就是最低字节有没有进位或借位)

	int a = 0x8;//0x8=1000,相当于右数第4个bit为1
	int b = 0x8;
	_asm mov eax, a;
	_asm mov ebx, b;
	_asm add eax, ebx;// 此处执行完毕AC会置1,因为发生了进位
	int a = 0x7;
	int b = 0x8;
	_asm mov eax, a;
	_asm mov ebx, b;
	// AC依然保持0,因为7+8=F,没有发生进位
	_asm add eax, ebx;

四:零标志位ZF(ZeroFlag)也叫ZR
计算指令(add等)产生的结果为0则置1,否则置0,注意如果两个数相加溢出了,也会置1,不管是如何得出0的,只要最终结果是0,那么ZR就会置1

	int a = 0x0;
	int b = 0x0;
	_asm mov eax, a;
	_asm mov ebx, b;
	// 下面这行代码走完之后,ZR变成1,因为0+0=0
	_asm add eax, ebx;

五:符号标志位SF(SignFlag)也叫PL
用来表示最高有效位,最高位是0,则置0,最高位是1则置1,在计算机中该标志位用来表示正负数

	int a = 0x00000000;
	int b = 0x88000000;
	_asm mov eax, a;
	_asm mov ebx, b;
	_asm add eax, ebx;//这行代码走完PL会置1

日记:
如果SF/PL=1,则说明这个数是某个数的补码形式,应该根据补码求解出原码,然后前面加上负号,但是,要注意,不能以SF/PL=1,就说明本次运算真正的结果是负数,当结果溢出之后,那么这个结果其实是正数,但是SF/PL依然是1,例如下面这段代码

mov ah,22H
mov bh,0A0H
// 实际结果应该是+130
// 但是ah里存的是82H,十进制是-126
sub ah,bh

所以要想得到一个结果真正是否是正负,还需要配合OF标志位(OV标志位),最终的结论如下
如果没溢出:SF/PL=1,则说明真正的结果为负,SF/PL=0说明结果为正
如果溢出:SF/PL=1,则说明真正的结果为正,SF/PL=0说明结果为负

六:陷阱标志位TF
陷阱标志指的是当前是一个单步调试的状态
七:中断标志位IF(Interrupt)
置1可屏蔽中断,后续再补上这个标志位 TODO
八:控制标志位DF(Direction),也叫方向标志
置1表示内存从高地址往低地址操作(减),置0则恰好相反
九:溢出标志位OF(Overflow)也叫OV
CF是无符号整数运算中用来表示溢出,而OF是在有符号整数中表示溢出,注意他俩的区别

	int a = 0x80000000;
	int b = 0x80000000;
	_asm mov eax, a;
	_asm mov ebx, b;
	// 发生了进位,算溢出,所以在这里OV的值会由0变成1
	_asm add eax, ebx;
	int a = 0x70000000;
	int b = 0x80000000;
	_asm mov eax, a;
	_asm mov ebx, b;
	// 发生了借位,也算溢出,所以在这里OV的值会由0变成1
	_asm add eax, ebx;

PUSHF和POPF指令

pushf是将标志寄存器(EFLAG)的值压入栈
popfs是从栈中弹出数据,放到标志寄存器中


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值