番禺网站开发公司国外网站模板
《汇编语言》- 读书笔记 - 第11章-标志寄存器
- 标志寄存器
- 指令与标志位关系
- 11.1 ZF(Zero Flag,零标志位)
- 11.2 PF(Parity Flag,奇偶标志位)
- 11.3 SF(Sign Flag,符号标志位)
- 处理无符号数
- 检测点 11.1
- 11.4 CF(Carry Flag,进位标志位)
- 加法进位
- 减法借位
- 11.5 OF(Overflow Flag,溢出标志位)
- 检测点 11.2
- 11.6 adc 指令(Add with Carry)
- 11.7 sbb 指令(SuBtraction with Borrow)
- 11.8 cmp 指令(Compare)
- 无符号数比较
- 有符号数比较
- 11.9 检测比较结果的条件转移指令
- 根据无符号数比较结果进行转移
- 根据有符号数比较结果进行转移
- 1. 编程
- 2. 编程
- 3. 编程
- 检测点 11.3
- 11.10 DF 标志和串传送指令(Direction Flag)
- movsb、movsw、rep
- cld、std
- 1. 编程
- 2. 编程
- 11.11 pushf 和 popf
- 检测点 11.4
- 11.12 标志寄存器在 Debug 中的表示
- 实验 11 编写子程序
- 参考资料
标志寄存器

| 寄存器 | 全称 | 含义 | 举例 |
|---|---|---|---|
| CF | Carry Flag | 进位标志位 | 若算术运算有进位/借位,则CF=1,否则CF=0。例如: ADD AX, BX后,如果结果导致了进位或借位,CF会被设置。 |
| PF | Parity Flag | (奇)偶标志位 | 根据运算结果中所有 bit 位1的个数是否为偶数来设置。若 1的个数为偶数,则 PF=1,否则 PF=0。例如: 0000 0011 则 PF=1,0000 0111 则 PF=0 |
| AF | Auxiliary Carry Flag | 辅助进位标志位 | 在BCD调整或某些算术运算(如加法和减法)中,当低4位发生进位或借位时 AF=1;否则 AF=0。 |
| ZF | Zero Flag | 零标志位 | 结果为零时,ZF=1;否则 ZF=0。例如: CMP AX, BX,如果AX与BX相等,则 ZF=1。 |
| SF | Sign Flag | 符号标志位 | 结果为负,则 SF=1,结果为正数或零,则 SF=0 CPU 在执行 add 等指令时,必然影响 SF 标志位。用不用看我们需要。如果我们声明的是 有符号数,编译器自动会判断 SF |
| TF | Trap Flag | 陷阱标志位 | 当TF=1时,CPU每执行一条指令后会引发一个单步中断,常用于调试。 |
| IF | Interrupt Flag | 中断允许标志位 | IF=1表示CPU可以响应可屏蔽中断;IF=0则禁止响应可屏蔽中断。 |
| DF | Direction Flag | 方向标志位 | 控制串操作指令的自动递增还是递减地址指针。DF=0表示递增,DF=1表示递减。 |
| OF | Overflow Flag | 溢出标志位 | 当算术运算的结果超出了寄存器所能表示的范围而产生溢出时,OF=1;否则 OF=0。 |
注意:在编程中,通常无需关心标志位的使用,因为编译器会自动处理。但在特殊情况下,可能需要显式使用标志位,此时需深入了解底层硬件和编译器特性。
指令与标志位关系
许多指令在执行时会根据操作结果影响标志位。以下是一些常见的情况:
会影响标志位的指令(包括但不限于):
| 算术运算指令 | add、adc、sub、sbb、mul、imul、div、idiv等 影响标志位:CF(进位/借位标志)、ZF(零标志)、SF(符号标志)、OF(溢出标志) |
|---|---|
| 逻辑运算指令 | and、or、xor、not、test 影响标志位: CF(某些情况下)、ZF(零标志)、PF(奇偶标志) |
| 移位指令 | shl、shr、sal、sar、rol、ror等 影响标志位: CF(进位/借位标志)、ZF(零标志)、OF(溢出标志) |
| 比较指令 | cmp、test 影响标志位: CF、ZF、SF、OF |
| 字符串处理指令 | scas、cmps等 影响标志位: ZF、SF、OF、AF、PF、CF(根据具体操作) |
不会直接影响标志位的指令(仅列举部分):
| 数据传送指令 | mov(单纯的数据复制不会改变标志位)push和pop(虽然它们间接影响栈指针,但并不会改变算术或逻辑运算相关的标志位) |
|---|---|
| 控制转移指令 | jmp、call、ret、loop等 这类指令不影响标志位,它们主要控制程序流程。 |
| 处理器控制指令 | cli、sti、hlt等 这类指令通常用于处理器状态控制,而不涉及数据计算,所以不直接影响标志位。 |
请注意,实际情况可能更复杂,某些指令在特定条件下也可能影响某些标志位。此外,有些指令可以通过修改EFLAGS寄存器中的标志位来实现更为复杂的条件判断。
11.1 ZF(Zero Flag,零标志位)
ZF(Zero Flag,零标志位)用于指示最近的算术或逻辑运算结果是否为零。在执行加法、减法、比较等指令后,CPU会根据操作结果自动更新 ZF。
具体来说:
当一个算术或逻辑运算的结果等于0时,ZF会被设置为1(即ZF=1),表示运算结果为零。
当运算结果不为0时,ZF会被清零(即ZF=0)。
11.2 PF(Parity Flag,奇偶标志位)
PF(Parity Flag,奇偶标志位)的设计初衷是为了检查和验证数据传输过程中的错误。在早期的计算机系统中,尤其是使用奇偶校验的硬件设计中,会对每个字节(8位)的数据进行奇偶校验,以确保在传输过程中没有出现错误。
奇偶校验是通过计算一个字节内“1”的个数来实现的,分为两种形式:
偶校验: 如果1的个数为偶数,则该字节被认为是有效的,此时PF设置为1。
奇校验: 如果1的个数为奇数,则该字节被认为是有效的,此时虽然也是PF标志,但意义是在奇校验情况下表示正确。
11.3 SF(Sign Flag,符号标志位)
结果为负,则 SF = 1;结果为非负数(包括正数和零),则 SF=0。
CPU在执行算术运算指令如 add、sub、mul、imul 等时,会根据运算结果的最高有效位更新SF标志位。不管你程序员用不用。
对于编译器而言,如果声明的是有符号整数,并且进行比较操作时,编译器可能会根据需要生成对应的条件转移指令,这些指令通常会参考SF以及其他标志位(如ZF、OF等)来判断数值的大小关系或者溢出情况。
例如:汇编代码中常见的 jns(Jump if Not Signed,即若结果是非负数则跳转)这样的条件转移指令就依赖于SF标志位。
总结来说:
SF标志位反映了算术运算结果的符号信息。- 执行涉及符号的
算术指令后,SF必然会被影响。(比如处理无符号数,我们不理SF即可) - 编译器在处理有符号数的比较和条件分支时,会自动利用SF和其他相关标志位来进行优化和控制流程。
处理无符号数
在处理无符号数时,SF(Sign Flag)标志位的直接用途并不明显。然而,在某些情况下,尽管SF主要设计用于表示有符号数的符号信息,但在特定场景下它也可以间接提供有用的信息:
-
循环移位操作: 在进行逻辑或算术右移时(如 shl、shr 或 sar 指令),对于无符号数来说,SF可以用来判断移位前最高位的内容。例如,当进行无符号数右移时,如果需要知道移位前的最高位是0还是1,可以在移位前查看SF。
-
条件转移指令: 尽管通常不推荐使用SF来判断无符号数比较结果,但在某些复杂条件转移中,SF可能和其他标志位一起被用作转移条件的一部分。比如,通过结合ZF和SF等标志位可以实现更复杂的条件测试,但这种情况较为少见,并且不如针对无符号数专门设计的标志位(如CF)直观。
-
低效或非标准的编程实践: 在极少数情况下,程序员可能会利用SF作为临时存储标志位,但这并不是其设计初衷,也非最佳实践。现代编程中一般会避免这样的做法。
总的来说,对于无符号数运算,程序员更多依赖于其他标志位,如CF(进位标志)来进行大小比较和溢出判断,而SF在无符号计算中的作用相对较小。
检测点 11.1
《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 11.1
11.4 CF(Carry Flag,进位标志位)
当执行算术运算时,CF用于记录运算过程中产生的进位或借位情况。
有就 CF=1 没有就 CF=0

- 当加法中有值从
最高有效位跑到假想的更高位处,说明发生了进位。 - 当进行减法时,被减数需要从
假想的更高位凭空假借1来计算,这就发生了借位。
CF(进位标志位): 主要与无符号数的算术运算相关。无符号数没有 “溢出” 的概念,只有进位和借位。当进行加法或减法运算时,如果结果导致了最高位出逃(对于二进制来说,就是最高有效位向更高位产生了进位或者借位),则CF会被设置为1。
对于无符号整数,这可以看作是单纯的数值大小超过了当前数据类型所能表示的最大范围,而这个“超出”并不会改变数值的正负性。
加法进位
在二进制加法中,如果两个二进制数相加时,在最低位(最右边)产生了进位,并且该进位需要继续向更高位(左边)进行累加,则称发生了进位。当最高有效位(MSB)也发生进位,意味着结果超出了当前数据类型的表示范围,对于无符号整数来说,这个超出的值跑到假想的更高位处,实际上在硬件层面无法直接存储,但在计算过程中 CF 会被设置为1,以表明发生了进位。
减法借位
在二进制减法中,被减数小于减数时,需要从高位借位来完成减法运算。
例如: 在8位寄存器中执行减法操作,如果最低位需要从更高位借位,那么实际上是借自一个假想的更高位(也就是第9位)。在实际硬件执行中,当发生借位时,会立即影响到CF标志位的状态:若发生借位,则CF置1;否则,CF清零。
- 总结
- 加法中的进位:当低位的结果超过了2(即产生了进位),并且这个进位传递到了更高位,则CF置1。
- 减法中的借位:当前的被减数小于减数时,需要从上一位借位才能完成减法,此时CF也会置1。
这种进位或借位不仅限于实际存在的寄存器位,而是根据运算逻辑可能扩展到更高的位。在真实的硬件实现中,CPU通过状态标志寄存器记录这些信息,而不是真的在内存中增加额外的位去存储进位或借位的结果。
最高有效位 就是 最高位 只是强调了它有效性及在数值表示中的重要地位。
11.5 OF(Overflow Flag,溢出标志位)
在进行有符号数运算的时候,如结果超过了机器所能表示的范围称为溢出。
OF 主要用于反映有符号数运算中的溢出情况。当两个同样大小类型的有符号数相加或相减后,其结果无法用同样的数据类型正确表示(即结果超出了该数据类型的最小值和最大值之间的范围),就会触发OF标志。具体而言,当两个正数相加得到一个负数,或者两个负数相加得到一个正数时,就发生了有符号数的溢出。
正数溢出示例:
+7FH (0111 1111) 最大正数
+ +01H (0000 0001)
-------------------+80H (1000 0000) 这个结果在8位有符号整数范围内是 -128,但实际上发生了正数溢出
此时,SF(符号标志)= 1,说明结果是一个负数。
负数溢出示例:
-127 (1000 0001)+ -1 (1111 1111)
-----------------------128 (1000 0000) 正确结果-128 (1000 0000)+ -1 (1111 1111)
----------------------+127(0111 1111 溢出导致的错误结果) 在8位有符号整数中,这个结果是 +127,发生了负数溢出
此时,SF(符号标志)= 0,但因为发生了溢出,逻辑上它应该是负数(-129)而不是一个正数。
总结一下:
- 对于
无符号数运算,如果结果超过了当前数据类型的最大值,则会发生进位,CF标志位将被设置。 - 对于
有符号数运算,如果结果超出了当前数据类型能够表示的最大正数或最小负数的范围,则会发生溢出,OF标志位将被设置。(这里的溢出就是符号位被翻转)
检测点 11.2
《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 11.2
11.6 adc 指令(Add with Carry)
adc | 指令是带进位的加法操作。 |
|---|---|
| 格式 | adc 操作对象1, 操作对象2 |
| 功能 | 操作对象1 = 操作对象1 +操作对象2 + CF |
| 比如 | adc ax,bx 实现的功能是:(ax) = (ax) + (bx) + CF |
- 应用场景
在连续的加法运算中需要考虑上一步的进位情况。通过adc指令,我们可以确保在多步加法过程中正确处理进位问题,这对于实现多字节加法等复杂计算非常有用。
此时可以:- 先
低位相加。(如果有进位,CF会被置1) - 再
高位相加,此时再加上CF就实现了进位。如果有更高位,可以继续。 - 在大数连续加法上可以不受限制。(如书中的例子:
两个 128 位数据进行相加)
- 先
| 名称 | add128 |
|---|---|
| 功能 | 两个 128 位数据进行相加。 |
| 参数 | ds:si 指向存储第一个数的内存空间。因数据为 128 位,所以需要8个字单元,由低地址单元到高地址单元依次存放 128 位数据由低到高的各个字。运算结果存储在第一个数的存储空间中。ds:di 指向存储第二个数的内存空间。 |
assume cs:code, ds:data
data segment; 8个WORD,共 128 位first dw 1111h,1111h,1111h,1111h,1111h,1111h,1111h,1111h; 8个WORD,共 128 位second dw 2222h,2222h,2222h,2222h,2222h,2222h,2222h,2222h
data endscode segment
start:mov ax,data ; 设置数据段mov ds,axmov ax,offset first ; 第一个数的偏移量mov si,axmov ax,offset second ; 第二个数的偏移量mov di,axcall add128 ; 调用 128位数加法。 first + second。 cs:0Fmov ax, 4c00H ; 退出程序 cs:12int 21H ; cs:15
; ------------------- 子程序 add128 ----------------
; 实现两个 128 位数据进行相加
; --------------------------------------------------
; 参数: ds:si 指向第一个数
; 参数: ds:di 指向第二个数
; 返回: ds:si 保存结果
; --------------------------------------------------
add128: push ax ; 备份寄存器push cxpush sipush disub ax,ax ; 设置 AX=0, CF=0mov cx,8 ; 8个word 需要循环 8 次
add128_s:mov ax,[si]adc ax,[di]mov [si],axinc siinc siinc diinc diloop add128_spop di ; 还原寄存器pop sipop cxpop axret
; ------------------- 子程序 add128 ----------------
code ends
end start

11.7 sbb 指令(SuBtraction with Borrow)
sbb | 是带借位减法指令,它利用了 CF 位上记录的借位值。 |
|---|---|
| 格式 | sbb 操作对象1, 操作对象2 |
| 功能 | 操作对象1 = 操作对象1 - 操作对象2 - CF |
| 比如 | sbb ax,bx 实现的功能是:(ax) = (ax) - (bx) - CF |
sbb 与 abc 是基于同样的思想设计的两条指令,一个加法一个减法。
不多废话。直接把上面add128 改改,来个 sub128 上代码:
assume cs:code, ds:data
data segment; 8个WORD,共 128 位first dw 2222h,2222h,2222h,2222h,2222h,2222h,2222h,2222h; 8个WORD,共 128 位second dw 1111h,1111h,1111h,1111h,1111h,1111h,1111h,1111h
data endscode segment
start:mov ax,datamov ds,axmov ax,offset firstmov si,axmov ax,offset secondmov di,axcall sub128 ; 128位数减法 cs:0Fmov ax, 4c00H ; 退出程序 cs:12int 21H ; cs:15
; ------------------- 子程序 sub128 ----------------
; 实现两个 128 位数据进行相减
; --------------------------------------------------
; 参数: ds:si 指向第一个数
; 参数: ds:di 指向第二个数
; 返回: ds:si 保存结果
; --------------------------------------------------
sub128: push axpush cxpush sipush disub ax,ax ; 设置 AX=0, CF=0mov cx,8 ; 8个word 需要循环 8 次
sub128_s:mov ax,[si]sbb ax,[di]mov [si],axinc siinc siinc diinc diloop sub128_spop dipop sipop cxpop axret
; ------------------- 子程序 sub128 ----------------
code ends
end start

11.8 cmp 指令(Compare)
cmp | 是比较指令,功能相当于减法但不保存结果,只更新标志寄存器。其它指令通过识别 标志寄存器来使用比较结果。 |
|---|---|
| 格式 | cmp 操作对象1, 操作对象2 |
| 功能 | 计算 操作对象1 - 操作对象2 但不保存结果,只更新标志寄存器。 |
| 比如 | cmp ax,ax,计算 (ax)-(ax) 结果为 0 不保存(ax内容不变)。仅影响 flag 的相关各位。指令执行后:zf=1,pf=1,sf=0,cf=0,of=0。 |
- 比较指令的设计思路,即:通过做
减法运算,影响标志寄存器来记录比较结果。 其它指令就可以通过标志寄存器反过来判断出比较结果,并加以利用。cmp指令同add、sub指令一样进行比较时对有符号、无符号操作是无差别的。下面我们分有符号、无符号两种情况来看:
无符号数比较看:ZF(是否为0),CF(是否进借位)
无符号数比较
无符号数比较看:ZF(是否为0),CF(是否进借位)
| 比较 | 对应减法 | ZF | CF | |
|---|---|---|---|---|
ax == bx | ax - bx = 0 结果为零 | 1 | ||
ax != bx | ax - bx ≠ 0 结果不为零 | 0 | ||
ax < bx | ax - bx 借位 | 1 | ||
ax >= bx | ax - bx 没借位(结果可能为零or不为零) | 0 | ||
ax > bx | ax - bx 没借位,并且结果不为零 | 0 | and | 0 |
ax <= bx | ax - bx 可能借位,,结果也可能为零 为零满足 =,借位满足<,得其一即满足 <= | 1 | or | 1 |
有符号数比较
有符号数比较看:ZF(是否为0),SF(是否为负),OF(是否溢出)
| 比较 | 对应减法 | ZF | SF | OF |
|---|---|---|---|---|
ax == bx | ax - bx = 0 结果为零 | 1 | ||
ax != bx | ax - bx ≠ 0 结果不为零 | 0 | ||
ax < bx | ax - bx 结果为负,没溢出 ax - bx 结果 为正,溢出 | 1 0 | 0 1 | |
ax >= bx | ax - bx 结果为正,没溢出 | 0 | 0 | |
ax > bx | ax - bx 溢出,导致结果为负 | 1 | 1 | |
ax <= bx | 小于和等于的条件组合 | 1or1 or | 1 0 | 0 1 |
对于有符号数的结果判断,主要依据是SF(是否为负)。
我们在做比较时要参考的是算数逻辑 上结果的正负。但在CPU工作层面 溢出 会导致符号翻转,所以我们判断 SF 的同时还要考虑 OF 的情况。
如果减法得到结果为正数,同时又发生了溢出,那原本算数逻辑上的符号就应该是负。
分析见上文 11.5 OF(Overflow Flag,溢出标志位)
11.9 检测比较结果的条件转移指令
本节学习一些根据 cmp 指令的比较结果进行工作的指令。(比较结果指相关标志位的值)
这些条件转移指令通常都和cmp相配合使用,就好像 call 和 ret 指令通常相配合使用一样。
(但并不是意味着这些转移指令必须跟在 cmp 后面,它们本质上只是根据 标志位 转移。)
与前面 cmp 小节一样,这里也要分有符号、无符号两种情况:
根据无符号数比较结果进行转移
| 指令 | 英文名 | 含义 | 检测标志位 |
|---|---|---|---|
je | Jump if Equal | == 则跳转 | ZF=1 |
jz | Jump if Zero | == 则跳转 | ZF=1 |
jne | Jump if Not Equal | != 则跳转 | ZF=0 |
jnz | Jump if Not Zero | != 则跳转 | ZF=0 |
jb | Jump if Below | < 则跳转 | CF=1 |
jc | Jump if Carry | < 则跳转 | CF=1 |
jnae | Jump if Not Above or Equal | < 则跳转 | CF=1 |
jnb | Jump if Not Below | >= 则跳转 | CF=0 |
jae | Jump if Above or Equal | >= 则跳转 | CF=0 |
jnc | Jump if Not Carry | >= 则跳转 | CF=0 |
ja | Jump if Above | > 则跳转 | CF=0 且 ZF=0 |
jna | Jump if Not Above | <= 则跳转 | CF=1 或 ZF=1 |
jbe | Jump if Below or Equal | <= 则跳转 | CF=1 或 ZF=1 |
cmp 与这些 条件转移 指令的配合体现了类似高级语言中 IF 的思想。
根据有符号数比较结果进行转移
工作原理与有符号数相同,只是检测的标志位不同。
| 指令 | 英文名 | 含义 | 检测的标志位 |
|---|---|---|---|
je / jz | Jump if Equal / Jump if Zero | == 则跳转 | ZF=1 |
jne / jnz | Jump if Not Equal / Jump if Not Zero | != 则跳转 | ZF=0 |
jg / jnle | Jump if Greater / Jump if Not Less or Equal | > 则跳转 | SF≠OF 且 ZF=0 |
jge / jnl | Jump if Greater or Equal / Jump if Not Less | >= 则跳转 | SF=OF |
jl / jnge | Jump if Less / Jump if Not Greater or Equal | < 则跳转 | SF≠OF |
jle / jng | Jump if Less or Equal / Jump if Not Greater | <= 则跳转 | SF=OF 或 ZF=1 |
1. 编程
- 编程,统计
data段中数值==8的字节的个数,用ax保存统计结果。
编程思路:初始设置(ax)=0,循环比较每个字节的值,如果==8就将inc ax。程序如下。
assume cs:code, ds:data
data segmentdb 8,11,8,1,8,5,63,38
data endscode segment
start:mov ax,datamov ds,axmov bx,0 ; ds:bx 指向第一个字节mov ax,0 ; 初始化累加器mov cx,8 s: cmp byte ptr [bx],8 ; 和8进行比较; --------------------------------------jne next ; 如果不相等转到 next,继续循环inc ax ; 如果相等就将计数值加 1; --------------------------------------next: inc bxloop s ; 程序执行后:(ax)=3mov ax, 4c00H ; 退出程序 CS:17int 21H
code ends
end start

assume cs:code, ds:data
data segmentdb 8,11,8,1,8,5,63,38
data endscode segment
start:mov ax,datamov ds,axmov bx,0 ; ds:bx 指向第一个字节mov ax,0 ; 初始化累加器mov cx,8 s: cmp byte ptr [bx],8 ; 和8进行比较; --------------------------------------je ok ; 如果相等转到 okjmp short next ; 如果不相等转到 next,继续循环ok: inc ax ; 如果相等就将计数值加 1; --------------------------------------next: inc bxloop s ; 程序执行后:(ax)=3mov ax, 4c00H ; 退出程序 CS:19int 21H
code ends
end start

第一个程序用 jne 检测 !=8 跳过 inc ax 进入下一次循环。
第二个程序用 je 检测 ==8 跳到 inc ax,否则 jmp short next 直接跳过 inc ax。
两个方案都能实现相同的效果。
2. 编程
- 编程,统计
data段中数值大于8的字节的个数,用ax保存统计结果。
编程思路:初始设置(ax)=0,循环比较每个字节的值,如果>8就将inc ax。程序如下。
assume cs:code, ds:data
data segmentdb 8,11,8,1,8,5,63,38
data endscode segment
start:mov ax,datamov ds,axmov bx,0 ; ds:bx 指向第一个字节mov ax,0 ; 初始化累加器mov cx,8 s: cmp byte ptr [bx],8 ; 和8进行比较; --------------------------------------jna next ; 如果不大于8转到 next,继续循环inc ax ; 如果大于8就将计数值加 1; --------------------------------------next: inc bxloop s ; 程序执行后:(ax)=3mov ax, 4c00H ; 退出程序 cs:17int 21H
code ends
end start

3. 编程
- 编程,统计
data段中数值小于8的字节的个数,用ax保存统计结果。
编程思路:初始设置(ax)=0,循环比较每个字节的值,如果<8就将inc ax。程序如下。
assume cs:code, ds:data
data segmentdb 8,11,8,1,8,5,63,38
data endscode segment
start:mov ax,datamov ds,axmov bx,0 ; ds:bx 指向第一个字节mov ax,0 ; 初始化累加器mov cx,8 s: cmp byte ptr [bx],8 ; 和8进行比较; --------------------------------------jnb next ; 如果不小于8转到 next,继续循环inc ax ; 如果小于8就将计数值加 1; --------------------------------------next: inc bxloop s ; 程序执行后:(ax)=2mov ax, 4c00H ; 退出程序 cs:17int 21H
code ends
end start

检测点 11.3
《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 11.3
11.10 DF 标志和串传送指令(Direction Flag)
DF 在串处理指令中,控制每次操作后 si、di 的增减。
串操作指令是指对内存中连续存储的一系列数据进行相同操作的一类指令。
| - | 含义 |
|---|---|
| DF=0 | 表示串操作过程中地址自动递增(向上)例如: 在 REP MOVSB指令中,源指针SI和目标指针DI每次操作后会递增1个字节。 |
| DF=1 | 表示串操作过程中地址自动递减(向下)例如: 在 REP MOVSB指令中,源指针SI和目标指针DI每次操作后会递减1个字节。 |
movsb、movsw、rep
- movsb(Move String Byte by Byte)
movsb | 从源地址向目标地址逐个字节地复制数据。 |
|---|---|
| 格式 | movsb |
| 功能 | 将 ds:si 指向的内存单元中的字节送入 es:di 中,然后根据 df 位的值,将 si 和 di 递增或递减。 |
- movsw(Move String Word by Word)
movsw | 与 movsb 类似,只是逐个字复制数据。 |
|---|---|
| 格式 | movsw |
- rep (Repeat)
rep 是一个前缀指令,它与一些串操作指令结合使用,以实现重复执行这些指令的功能。
rep 指令根据 cx 来决定要重复执行多少次。
movsb 和 movsw 一般都和 rep 配合使用 rep movsb 实现的功能就类似:
s: movsbloop s
cld、std
- cld(Clear Direction Flag)
cld指令:将标志寄存器的df位置0。 - std(Set Direction Flag)
std指令:将标志寄存器的df位置1。
1. 编程
编程,用串传送指令,将 data 段中的第一个字符串复制到它后面的空间中。
assume cs:code
data segmentdb 'welcome to masm!'db 16 dup(0)
data ends
code segment
start:mov ax,datamov ds,axmov si,0 ; ds:si 指向 data:0mov es,axmov di,16 ; es:di 指向 data:0010mov cx,16 ; (cx)=16,rep 循环 16 次cld ; 设置 df=0,正向传送(si,di 递增)rep movsbmov ax, 4c00Hint 21H
code ends
end start

2. 编程
编程,用串传送指令,将 F000H 段中的最后 16 个字符复制到 data 段中。
assume cs:code
data segmentdb 16 dup(0)
data ends
code segment
start:mov ax,0f000hmov ds,axmov si,0ffffh ; ds:si 指向 f000:ffffmov ax,datamov es,axmov di,15 ; es:di 指向 data:000Fmov cx,16 ; (cx)=16,rep 循环 16 次std ; 设置 df=1,逆向传送(si,di 递减)rep movsbmov ax, 4c00Hint 21H
code ends
end start

11.11 pushf 和 popf
pushf 和 popf,为直接访问标志寄存器提供了一种方法。
-
pushf(Push Flags)
pushf是将标志寄存器的值压栈。 -
popf(Pop Flags)
popf是从栈中弹出数据,送入标志寄存器。
检测点 11.4
《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 11.4
11.12 标志寄存器在 Debug 中的表示

| 标志位 | 简写 | SET (a 1-bit) | CLEARed (a 0-bit) |
|---|---|---|---|
| Overflow | OF | OV (Overflow) | NV [No Overflow] |
| Direction | DF | DN (decrement) | UP (increment) |
| Interrupt | IF | EI (enabled) | DI (disabled) |
| Sign | SF | NG (negative) | PL (positive) |
| Zero | ZF | ZR [zero] | NZ [Not zero] |
| Auxiliary Carry | AF | AC | NA [No AC] |
| Parity | PF | PE (even) | PO (odd) |
| Carry | CF | CY [Carry] | NC [No Carry] |
实验 11 编写子程序
《汇编语言》- 读书笔记 - 实验11 编写子程序
参考资料
A Guide to DEBUG - The “FLAGS” REGISTER
