《汇编语言(第四版)》 . 王爽著 . 清华大学出版社 . 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