标志寄存器

标志寄存器


这就是计算机中的标志寄存器,说到标志我们就应该想到flag,bool类型。而一个bool类型用1bit就可以表示了,所以我们谈论这个32位的标志寄存器,更多的时候是讨论其中的某一位。
比如0位,2位,4位,都是cpu中设定好的用途,就跟通用寄存器一样,有自己的名字。比如C位,P位,O位。

进位标志位CF(carry flag)

如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。

三个实验:

mov al,0xff
add al,2   // c位变成1
mov al,0xfe // mov不是运算所以C位不变
// C位手动清零
add al,2 // c位又变成1
// C位手动清零
mov ax,0xff
add ax,2  // c位已经是0
// =========================重点
// 标志寄存器在学习过程中,我们一定要明白数据的宽度 
//【mov ax,0xff 】中,数据的宽度是16位,add之后,确实是进位了,但不是最高位的进位

补充:什么是运算?
mov不算是运算,其他的加减乘除异或等都是运算

奇偶标志位:PF(Parity Flag)

PF 反应运算结果中“1”的个数的奇偶性,如果1的个数是偶数,则P位是1,如果1的个数是奇数,则P位是0

实验

MOV AL,3  // 00001011 p位:0
add al,2  // 00001010 P位:1

辅助进位标志AF(Auxiliary Carry Flag)

在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:
(1)、在字节操作时,发生低字节向高字节进位或借位时;
(2)、在字节操作时,发生低4位向高4位进位或借位时。
大白话说下,就是运算时,把位划分成两半,低位的一半的第一位如果向高位进位(加)或者借位(减)时,A位就是1
如下图,就看突出的那一位
32位运算: _ _ _ _ - _ _ _
16位运算: _ _ - _
8位运算: _ -

实验:

// 第一组
MOV EAX,0x55EEFFFF
ADD EAX,2    // A位变1
// 第二组
MOV AX,5EFE  
add ax,2  // A位又变1
// 第三组
MOV AL,4E
add al,2 // A位又变1

零标志ZF(Zero Flag)

零标志ZF用来反映运算结果是否为0
如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。

实验

XOR EAX,EAX  // Z位:1
// 这句话的作用有两个
// 1.将EAX的值变为1
// 2.将标志位Z位置为1。如果[mov eax,0] 的话就没有第二个作用了,mov就不是运算

符号标志SF(Sign Flag)

符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。
特别注意:这里的最高位说的是二进制的最高位,所以只能是0或1

MOV AL,7F
ADD AL,2   // 1

溢出标志OF(Overflow Flag)

溢出标志OF用于反映有符号数加减运算所得结果是否溢出。
如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。

最高位进位(CF)和溢出(OF)的区别?
这里主要涉及到了无符号整数和有符号整数。计算机在存储的时候,并不知道自己存储的是有符号整数还是无符号整数。只有使用的人才知道,就是程序员喽。
C位是做无符号运算时该关注的
O位是做有符号运算时该关注的

想知道现在计算的结果有没有溢出,是看CF位还是OF位?
我要看那个取决于我做的是有符号还是无符号运算。
如果你知道自己做的是无符号运算,你只用看C位,不用管O位
如果你知道自己的做的是有符号运算,只要看O位,不用管C位

好好看这个图就什么都明白了



正数+负数,一定在圈内,永远不会溢出
正数+正数,如果结果为负数(超过7F内),一定溢出。因为越界了,两个正数相加不应该是负数。

说结果之前,一定要指定到底是无符号运算还是有符号预算。


image.png

自己这个分析判断是错误的,其实只要是圈上的点可以表示的,都没有溢出,圈上的店不能表示的,就是溢出了。
只是有符号的话,只有右边区域表示正数,左边区域表示负数
无符号的话,整个区域都可以表示

和标志寄存器相关的指令

ADC指令:带进位加法

百度百科:
ADC 带进位的加法指令 ADC Reg/Mem, Reg/Mem/Imm 功能,将目的操作数和源操作数相加再加低位进位,结果送入目的的地址 dst+src+cf->dst, 受影响的标志位:AF、CF、OF、PF、SF和ZF,该指令的功能是把源操作数和进位标志位CF的值(0/1)一起加到目的操作数中。

实验

MOV AL,1
MOV CL,2
ADC AL,CL //按照我们正常的ADD指令,此时AL中应该是3
// 但是ADC指令是带进位的加法,它会把c位中的值也给加上。
// 如果此时cf中的值是1,那结果:AL中的值是4,cf的值:0

注意事项:1.两边

SBB指令:带借位减法

百度百科的解释很明确
SBB:带借位减法, 格式:SBB DST,SRC, 执行的操作:(DST)←(DST)-(SRC)-CF,其中CF为进位的值。 SBB Compents :他们组成了Application .他们以何种方式组合是由SLEE来确定的。

实验

MOV AL,3
MOV CL,1
SBB AL,CL 
// 分两种情况:
// 1. 如果cf是0,那么结果和我们预想的一样,2
// 2. 如果cf是1,那么结果还会减1,结果al变为1了

XCHG指令:交换数据

百度百科
交换指令XCHG是两个寄存器,寄存器和内存变量之间内容的交换指令,两个操作数的数据类型要相同,可以是一个字节,也可以是一个字,也可以是双字

说明什么?
我们交换的是两个容器,不能是立即数
而且交换的两个容器不能都是内存

// 实验:
MOV AL,1
MOV CL,3
XCHG AL,CL  // AL变成3,CL变成了1

XCHG DWORD PTR DS:[0X0019FF74],EAX

MOVS指令:移动数据


看了一下通用寄存器中EDI和ESI的分工:

再回顾一下通用寄存器的划分:
https://xuxiaofeng.gitlab.io/2018/12/12/study-%E7%BC%96%E7%A8%8B%E8%BE%BE%E4%BA%BA-%E6%BB%B4%E6%B0%B4%E9%80%86%E5%90%913%E6%9C%9F%E5%AD%A6%E4%B9%A0-2018-12-12-%E8%BF%9B%E4%B8%80%E6%AD%A5%E5%AD%A6%E4%B9%A0%E5%AF%84%E5%AD%98%E5%99%A8/

现在我们来解释MOVS指令

movs指令是用来复制一个数据项(字节,字或双字)从源字符串到目标字符串。原字符串又ESI/SI/DH 指出,目标字符串又EDI/DI/BH指出。(具体又那个指出,我们需要看使用时定义的单位)

这里还有一段解释:
MOVS指令可以把由(SI)指向的数据段中的一个字(或字节)传送到由(DI)指向的附加段中的一个字(或字节)中去,同时根据方向标志(df标志寄存器)及数据格式(字 或字节)对SI和DI进行修改

在执行该指令前,应该先做好以下 准备工作:
1) 把存放于数据段中的源串首地址(如反向传送则应是末地址)放入SI寄存器中;
2) 把将要存放数据串的附加段中的目的串首地址(或反向传送时的末地址)放入DI寄存器中;
3) 建立方向标志。

实验
首先说明一下,我们之前碰到内存的时候,我们总是这样表示DS:[],没错。但是碰到EDI表示内存地址单元时,我们应该这样ES:[],所以往下,我们会经常看到这样的字符:ES:[EDI] (这里涉及到段、页的概念)

 1.直接输入movs,点击确定,编辑器就会自动给我们生成下面的额语句
  充分说明了这个指令是针对EDI和ESI的
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]  
mov edi,0019ff88
mov esi,0019ff80
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]  
结果
edi:0019ff8c
esi:0019ff84
并且刚才edi对应内存编号中的值和dsi对应内存编号中的值确实做了交换
我们发现EDI和ESI中的值都+4 了。这是有D位(df标志寄存器决定的)

所以这个MOVS指令有两个主要影响,一是真的交换了寄存器对应内存地址单元中的值,二是根据DF标志寄存器中的值,让ESI和EDI都进行一些位移。

STOS指令:讲Al/AX/EAX的值存储到[EDI]指定的内存单元

到底是复制AL还是AX还是EAX,是又我们指定的内存宽度决定的
。复制完毕后,EDI的变化方向是由我们的D位(df标志寄存器)决定的。

// 实验
mov eax,12345678
mov edi,0019ff88
直接数据stos,确定酒水弹出下面的值
STOS DWORD PTR ES:[EDI]
运行结果(D位此时是0)
DEI:0019FF8C
内存单元0019FF88中的值:12345678

REP指令:按计数寄存器 (ECX) 中指定的次数重复执行字符串指令

这里有一个把movs和rep指令糅合在一起的解释

MOVS指令可以把由(SI)指向的数据段中的一个字(或字节)传送到由(DI)指向的附加段中的一个字(或字节)中去,同时根据方向标志及数据格式(字 或字节)对SI和DI进行修改。当该指令与前缀REP联用时,则可将数据段中的整串数据传送到附加段中去。这里源串必须在数据段中,目的串必须在附加段 中,但源串允许使用段跨越前缀来修改。在与REP联用时还必须先把数据串的长度送到CX寄存器中,以便控制指令结束。因此在执行该指令前,应该先做好以下 准备工作:
1) 把存放于数据段中的源串首地址(如反向传送则应是末地址)放入SI寄存器中;
2) 把将要存放数据串的附加段中的目的串首地址(或反向传送时的末地址)放入DI寄存器中;
3) 把数据串长度放入CX寄存器;
4) 建立方向标志。
在完成这些准备工作后就可使用串指令传送信息了

MOV ECX,10
REP MOVSD
REP STOSD
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容