《汇编语言(第四版)》 . 王爽著 . 清华大学出版社 . 2019
实验 11 编写子程序 
标志寄存器 
8086CPU 中有 16 位标志寄存器(flag),其中存储的信息被称为程序状态字(PSW),其作用有: 
1)用来存储相关指令的某些执行结果; 
2)用来为 CPU 执行相关指令提供行为依据 
3)用来控制 CPU 的相关工作方式
标志寄存器的各个标志位 
记法: 
记它的英文 
Carry Flag(CF:进位标志位) 
Overflow Flag(OF:溢出标志位) 
Direction Flag(DF:方向标志位) 
Sign Flag(SF:符号标志位) 
Zero Flag(ZF:零标志位) 
Parity Flag(PF:奇偶标志位)
pushf 和 popf 
pushf:将标志寄存器的值压栈 
popf:从栈中弹出数据,送入标志寄存器中
检测点 11.1 
mov、push、pop 等传送指令的执行对标志寄存器没有影响 
注意 PF 记录的是相关指令执行后其结果的所有 bit 位中的 1 的个数的奇偶,不是结果的奇偶
1 2 3 4 5 6 7 sub  al ,al          mov  al ,1           push  ax            pop  bx             add  al ,bl          add  al ,10          mul  al             
 
检测点 11.2 
1 2 3 4 5 6 7 8 9 sub  al ,al          mov  al ,10H         add  al ,90H         mov  al ,80H         add  al ,80H         mov  al ,0FCH        add  al ,05H         mov  al ,7DH         add  al ,0BH         
 
cmp 指令 
cmp 是比较指令,它的功能相当于减法指令,但不保存结果,其执行后将对标志寄存器产生影响
cmp 通常与条件转移指令相配合使用,条件转移指令检测标志寄存器的相关标志位,根据检测的结果来决定是否修改 IP
1 2 3 4 5 6 7 8 9 10 11 12 13 je           jne          js                       jns                      jg           jge          jl           jle          ja           jae          jb           jbe          
 
检测点 11.3 
(1)
1 2 3 4 cmp  al ,32          jb  s0cmp  al ,128         ja  s0
 
(2)
1 2 3 4 cmp  al ,32          jna  s0cmp  al ,128         jnb  s0
 
注意满足逻辑即可
检测点 11.4 
AX=0045H 
1 2 3 4 5 6 7 8 9 10 mov  ax ,0 push  ax popf mov  ax ,0fff0h add  ax ,0010h             pushf                    pop  ax                   and  al ,11000101B         and  ah ,00001000B                                  
 
一些例程 
编写子程序,对两个 128 位数据进行相加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 add128:      push  ax             push  cx              push  si              push  di              sub  ax ,ax                       mov  cx ,8       s:      mov  ax ,[si ]            adc  ax ,[di ]             mov  [si ],ax              inc  si              inc  si              inc  di              inc  di              loop  s             pop  di              pop  si              pop  cx              pop  ax              ret                            
 
编程,统计 data 段中数值为 8 的字节个数,用 ax 保存统计结果。
比较下面两个程序的写法,注意使用 cmp 和条件转移指令时的编程思想
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 assume  cs :code,ds :datadata segment        db  8 ,11 ,8 ,1 ,8 ,5 ,65 ,38  data ends code segment  start:       mov  ax ,data            mov  ds ,ax                             mov  bx ,0                              mov  ax ,0                              mov  cx ,8      s:       cmp  byte  ptr  [bx ],8                  jne  next                             inc  ax                     next:       inc  bx             loop  s                               mov  ax ,4c00h              int  21h  code ends end start 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 assume  cs :code,ds :datadata segment        db  8 ,11 ,8 ,1 ,8 ,5 ,65 ,38  data ends code segment  start:       mov  ax ,data            mov  ds ,ax                             mov  bx ,0                              mov  ax ,0                              mov  cx ,8      s:       cmp  byte  ptr  [bx ],8                  je  ok                                jmp  short next              ok:       inc  ax                    next:       inc  bx             loop  s             mov  ax ,4c00h              int  21h                    code ends end start 
 
第一个程序更为精简,它用 jne 指令检测不等于 8 的情况,从而间接地检测了等于 8 的情况
编程,用串传送指令,将 data 段中的第一个字符串复制到它后面的空间中。
使用串传送指令(rep movsb / rep movsw)进行数据的传送,需要提供 
1)传送的原始位置:ds:si 
2)传送的目的位置:es:di 
3)传送的长度:cx 
4)传送的方向:df
8086CPU 提供下面两条指令对标志寄存器的 df 位进行设置 
cld 指令:将 df 位置 0 
std 指令:将 df 位置 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 assume  cs :code,ds :datadata segment        db  'Welcome to masm!'        db  16  dup (0 ) data ends code segment  start:       mov  ax ,data            mov  ds ,ax              mov  si ,0                        mov  es ,ax              mov  di ,16                       mov  cx ,16                       cld                             rep  movsb              mov  ax ,4c00h              int  21h  code ends end start 
 
编程,用串传送指令,将 F000H 段中的最后 16 个字符复制到 data 段中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 assume  cs :code,ds :datadata segment        db  16  dup (0 ) data ends code segment  start:       mov  ax ,0f000h             mov  ds ,ax              mov  si ,0ffffh                   mov  ax ,data             mov  es ,ax              mov  di ,15                       mov  cx ,16                       std                             rep  movsb              mov  ax ,4c00h              int  21h  code ends end start 
 
实验任务 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 assume  cs :codesg,ds :datasgdatasg segment        db  "Beginner's All-purpose Symbolic Instruction Code." ,0  datasg ends codesg segment    begin:     mov  ax ,datasg            mov  ds ,ax              mov  si ,0              call  letterc             mov  ax ,4c00h              int  21h  letterc:     push  si             push  ax       s1:     cmp  byte  ptr  ds :[si ],0                     je  ok             cmp  byte  ptr  ds :[si ],61h                    jb  s2                                      cmp  byte  ptr  ds :[si ],7ah              ja  s2             mov  al ,ds :[si ]                             and  al ,11011111b                            mov  ds :[si ],al       s2:     inc  si             inc  cx                                      loop  s1      ok:     pop  ax             pop  si              ret               codesg ends end begin 
 
用 Debug 跟踪程序运行
 
汇编语言实验合集 
汇编语言实验合集 
实验 1 查看 CPU 和内存,用机器指令和汇编指令编程  
实验 2 用机器指令和汇编指令编程  
实验 3 编程、编译、连接、跟踪  
实验 4 [bx] 和 loop 的使用  
实验 5 编写、调试具有多个段的程序  
实验 6 实践课程中的程序  
实验 7 寻址方式在结构化数据访问中的应用  
实验 8 分析一个奇怪的程序  
实验 9 根据材料编程  
实验 10 编写子程序  
课程设计 1  
实验 11 编写子程序  
实验 12 编写 0 号中断的处理程序  
实验 13 编写、应用中断例程  
实验 14 访问 CMOS RAM  
实验 15 安装新的 int9 中断例程  
实验 16 编写包含多个功能子程序的中断例程  
实验 17 编写包含多个功能子程序的中断例程  
课程设计 2