java打印对象内存地址 分布式事务 事务消息 分布式事务 几种解决方案 分布式事务-Seata 分布式事务-Seata 分布式事务-LCN-TCC 分布式事务-LCN 分布式事务-消息队列-定时任务-本地事件表 Zuul网关实战02 Zuul网关实战01 灰度发布落地实战2 灰度发布落地实战1 Gsnova on Heroku build Systemd Debian system initialization manage multi id_rsa ubuntu 64bits cannot run 32bits app REHL power auditing Debug Assembly for ARMv8 on QEMU ARM体系结构--寄存器 Run Debian iso on QEMU ARMv8 QEMU ARM64 guide cross compiler install buildroot install QEMU install python入门--数据结构 python入门--内置数据类型 python入门--类 异常 python入门--条件表达式 方法 python入门--数字 字符串 数组 RTC驱动分析 块设备驱动 TCP UDP socket 触摸屏驱动 USB驱动 LED按键中断 LCD 驱动 驱动信号 根文件系统 实验 内核实验 字符设备驱动程序 绪论 uboot 实验 LCD 实验 系统时钟和UART 中断控制器 Nand Flash控制器 MMU 实验 储存管理器实验 GPIO实验 点亮LED 编译加载驱动 制作烧写内核 dnw替代方法 MINI2440 TQ2440安装配套Linux 使用NFS 制作烧写跟文件系统 grub引导Windows 烧写裸版程序-linux Ubuntu 网络没有 eth0 Linux自动挂载 烧写裸板程序 电路基础 Mac词典 Vim插件 Assembly 综合研究 Assembly 指令总结 Assembly 直接定址表 Assembly 使用BIOS进行键盘输入和磁盘读写 Assembly 外中断 Assembly 端口 Assembly int指令 Assembly 内中断 Assembly 标志寄存器 Assembly 转移指令的原理 Assembly Call和ret指令 Assembly 数据处理两个基本问题 Assembly 灵活定位内存地址 Assembly 包含多个段的程序 Assembly [bx] loop Assembly 第一个程序 Assembly 寄存器 (内存访问) Assembly 寄存器 AWS VPN with EC2 hidden file in picture(linux) Assembly 基础 idea shortcuts 常用快捷键 idea plugin folder install ruby and jekyll

Assembly 标志寄存器

2014年09月25日

简称flag,flag寄存器是按位起作用的

有的指令的执行是影响标志寄存器的,如:add、sub、mul、div、inc、or、and等,他们大都是运算指令

有的指令的执行对标志寄存器没有影响,如:mov、push、pop等,他们大都是传送指令

具有以下3个作用:

  1. 用来存储相关指令的某些执行结果
  2. 用来为CPU执行相关指令提供行为依据
  3. 用来控制CPU的相关工作方式
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
        OF DF IF TF SF ZF   AF   PF   CF

###ZF标志 flag的第6位是ZF,零标志位。它记录相关指令执行后,其结果是否为0。如果结果为0,zf=1;如果结果不为0,zf=0

例:

mov ax,1
sub ax,1

执行后,结果为0,则zf=1

###PF标志 flag的第2位是PF,奇偶标志位,它记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数。

如果1的个数为偶数,则pf=1

如果为1的个数为奇数,则pf=0

例:

mov al,1
add al,10

执行后,结果为00001011B,其中有3(奇数)个1,则pf=0

###SF标志 flag的第7位是SF,符号标志位,他记录相关指令执行后,其结果是否为负

如果为负,sf=1

如果非负,sf=0

计算机通常用补码来表示有符号数据,计算机中的一个数据可以看做是有符号数,也可以看成无符号数

比如:

00000001B,可以看做无符号数1,或有符号数+1 10000001B,可以看做无符号数129,也可以看做有符号数-127

对于同一个二进制数,计算机可以将它当做无符号数据来运算,也可以当做有符号数据来运算,比如:

mov al,10000001B
add al,1

结果:10000010B

可以将add指令运算当做无符号数运算,那么add指令相当于计算129+1,结果为130(10000010B);

也可以将add指令运算当做有符号运算,那么add指令相当于计算-127+1,结果为-126(10000010B)

SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负

例:

mov al,10000001B
add al,01111111B

执行后,结果为0,sf=0,结果为非负

###CF标志(无符号运算) flag的第0位是CF,进位标志位,一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值

例:

mov al,98H
add al,al	;执行后:(al)=30H,CF=1,CF记录了从最高有效位向更高位的进位值
add al,al	;执行后:(al)=60H,CF=0,因为这步操作没有产生进位值

###OF标志(有符号运算) flag的第11位是OF,溢出标志位。一般情况下,OF记录了有符号数运算的结果是否发生了溢出

如果发生溢出,OF=1

如果没有发生溢出,OF=0

在进行有符号数运算的时候,如结果超过了机器所能表示的范围称为溢出

对于8位的有符号数据,机器所能表示的范围就是-128~127

对于16位有符号数据,机器所能表示的范围是-32768~32767

如果运算结果超出了机器所能表达的范围,将产生溢出

注意,这里所讲的溢出,只是对有符号数运算而言

例:

mov al,0F0H
add,88H

add指令执行后:CF=1,OF=1。对于无符号数运算,OF0H(240)+88H(136)=376,超出0~255有进位,CF=1

对于有符号数,0F0H=-16,88H=-120,-16-120=-136超出-128~127范围,OF=1

###adc指令 adc是带进位加法指令,它利用了CF位上记录的进位值

adc执行后,也可能产生进位值(CF变化)

例:

mov ax,2
mov bx,1
sub bx,ax
adc ax,1

执行后,(ax)=4。adc执行时,相当于计算:(ax)+1+CF=2+1+1=4

mov ax,1
add ax,ax
adc ax,3

执行后,(ax)=5。adc执行时,相当于计算:(ax)+3+CF=2+3+0=5

adc指令的意义:对任意大的数据进行加法运算

计算:1EF000H+201000H 结果放在ax(高16位)和bx(低16位)中

mov ax,001EH
mov bv,0F000H
add bx,1000H
adc ax,0020H

###sbb指令 带借位减法指令,它利用了CF位上记录的错位值

sbb执行后,也对CF进行设置,可以对任意大的数据进行减法运算

计算:003E1000H-00202000H

mov bx,1000
mov ax,003EH
sub bx,2000H
sbb ax,0020H

###cmp指令 cmp是比较指令,功能相当于减法指令,只是不保存结果,cmp指令执行后,将对标志寄存器产生影响

例:

mov ax,8
mov bx,3
cmp ax,bx

执行后,(ax)=8,zf=0,pf=1,sf=0,cf=0,of=0

cmp执行也包含两种含义:进行无符号数运算和进行有符号数运算

###检测比较结果的条件转移指令 所有的条件转移指令的转移位移都是[-128,127]

因为cmp指令可以同时进行两种比较,无符号数比较和有符号数比较,所以根据cmp指令执行结果进行转移的指令也分为两种:

  • 无符号数的比较结果进行转移的条件转移指令(检测zf、cf的值)
  • 有符号数的比较结果进行转移的条件转移指令(检测sf、of、zf的值)

常用的根据无符号数的比较结果进行转移的条件转移指令:

指令 含义 检测的相关标志位
je 等于则转移 zf=1
jne 不等于则转移 zf=0
jb 低于则转移 cf=1
jnb 不低于则转移 cf=0
ja 高于则转移 cf=0且zf=0
jna 不高于则转移 cf=1或zf=1

记忆方法:

e:表示equal

ne:表示not equal

b:表示below

nb:表示not below

a:表示above

na:表示not above

cmp与je等联合使用的时候表现出来的功能,有些像高级语言中的IF语句

###DF标志和串传送指令 flag的第10位是DF,方向标志位。在串处理指令中,控制每次操作后si、di的增减

df=0 每次操作后 si、di递增

df=1 每次操作后 si、di递减

串传送指令:movsb

功能:执行movsb指令相当于:

mov es:[di],byte ptr ds:[si]	;8086并不支持这样的指令,这里只是描述

如果df=0

inc si
inc di

如果df=1

dec si
dec di

也可以传送一个字,用movsw指令

功能如下:

mov es:[di],word ptr ds:[si]	;8086不支持这样的指令,这里只是个描述

如果df=0
add si,2
add di,2

如果df=1
sub si,2
sub di,2

一般来说,movsb和movsw都配合rep使用,格式如下:

rep movsb

用汇编语法来描述rep movsb的功能就是:

s:movsb
  loop s

可见,rep的作用是根据cx的值,重复执行后面的串传送指令

8086CPU提供下面两条指令对DF位进行设置:

  1. cld指令:将标志寄存器的df位置0
  2. std指令:将标志寄存器的df位置1

例:编程,用串传送指令进行数据的传送,将data段中的第一个字符串复制到他后面的空间中

assume cs:code

data segment
	db 'Weldome to masm!'
	db 16 dup (0)
data ends

code segment
	mov ax,data
	mov ds,ax
	mov si,0	;ds:si指向data:0
	mov es,ax
	mov di,16	;es:di指向data:0010
	mov cx,16	;cx=16,rep循环16次
	cld			;设置df=0,正向传送
	rep movsb
code ends

end start

###pushf和popf pushf是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中。

###标志寄存器在Debug中的表示 |标志|值为1的标记|值为0的标记| |—| |of|OV|NV| |sf|NG|PL| |zf|ZR|NZ| |pf|PE|PO| |cf|CY|NC| |df|DN|UP|