实验4 8086标志寄存器及中断
一、实验目的
1. 理解标志寄存器用途,理解常用标志位CF, ZF, OF, SF, TF, IF的用途和意义。
2. 理解条件转移指令je, jz, ja, jb, jg, jl等的跳转原理,掌握组合使用汇编指令cmp和条件转移指令实现分支和循环的用法
3. 了解软中断指令的用法,体验和理解中断原理4. 综合应用寻址方式和汇编指令完成简单应用编程
二、实验准备复习教材
「第10章 call和ret指令」、「第11章标志寄存器」学习教材「第12章内中断」、「第13章 int指令」
三、实验内容
1. 实验任务1
验证性实验:有些汇编指令会影响到标志寄存器中的一个或多个状态标志位。在debug环境中,分别实践、观察:
1 assume cs:code,ds:data 2 data segment 3 x dw 1020h,2240h,9522h,5060h,3359h,6652h,2530h,7031h 4 y dw 3210h,5510h,6066h,5121h,8801h,6210h,7119h,3912h 5 data ends 6 code segment 7 start: 8 mov ax,data 9 mov ds,ax 10 mov si,offset x 11 mov di,offset y 12 call add128 13 14 mov ah,4ch 15 int 21h 16 17 add128: 18 push ax 19 push cx 20 push si 21 push di 22 23 sub ax,ax 24 25 mov cx,8 26 s: mov ax,[si] 27 adc ax,[di] 28 mov [si],ax 29 30 inc si 31 inc si 32 inc di 33 inc di 34 loop s 35 36 pop di 37 pop si 38 pop cx 39 pop ax 40 ret 41 code ends 42 end start 43
line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?
1 add si, 2 2 add di, 2
不能替换,因为add操作会对CF的值产生影响,影响进一步的sub和adc指令。
在debug中调试,观察数据段中做128位加之前和加之后,数据段的值的变化。给出调试观察截图。

2. 实验任务2
此部分书写内容:
程序task2.asm源码
1 assume cs:code, ds:data 2 data segment 3 str db 80 dup(?) 4 data ends 5 code segment 6 start: 7 mov ax, data 8 mov ds, ax 9 movsi, 0 10 s1: 11 mov ah, 1 12 int 21h 13 mov [si], al 14 cmp al, '#' 15 je next 16 inc si 17 jmp s1 18 next: 19 mov ah, 2 20 mov dl, 0ah 21 int 21h 22 mov cx, si 23 mov si, 0 24 s2: 25 mov ah, 2 26 mov dl, [si] 27 int 21h 28 inc si 29 loop s2 30 mov ah, 4ch 31 int 21h 32 code ends 33 end start
运行测试截图
回答问题运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果。结合运行结果,理解代码并回答问题:

①汇编指令代码line11-18,实现的功能是?
答:从键盘上读取输入的字符,并保存到ds:[si],每读入一个就判断是否为#,如果是则不保存,转跳至标号next处执行;如果不是则si + 1并继续读入下一个字符。
②汇编指令代码line20-22,实现的功能是?
答:打印一个回车(换行符)
③汇编指令代码line24-30,实现的功能是?
答:打印字符串,并且不会把#打出来
3. 实验任务3
此部分书写内容:
task3.asm源码
assume ds:data, cs:code, ss:stack data segment x dw 91, 792, 8536, 65535, 2021, 0 len equ $ - x data ends stack segment dw 8 dup(?) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 16 mov cx, len/2 mov ax, word ptr ds:[di] ; 把数据放入al add di, 2 ; di指针后移2字节 push cx ; 把cx保存起来, 子程序中会修改cx值 call printNumber ; 打印数字 call printSpace ; 打印空格 pop cx ; 恢复cx loop print mov ah, 4ch int 21h printNumber: mov bx, 0 ; 获取之前位数为0 ; 逐位获取数字 ; getEach循环: 获取每一位,然后压入栈中 getEach: ; 除数放在16位寄存器bp中 mov bp, 10 ; 除10运算 mov dx, 0 ; 由于除数是16位寄存器,dx也是被除数一部分,需要置零 div bp ; 数据除10 push dx ; 将数字压入栈中 inc bx ; 位数+1 mov cx, ax ; 除法商赋给cx inc cx ; 由于loop时会-1,这里先+1,防止出现负数 loop getEach ; 打印数字 mov cx, bx printEach: pop dx add dl, 30h mov ah, 2 int 21h loop printEach ret ; 子程序: printSpace ; 功能: 打印空格 printSpace: mov ah, 2 mov dl, 20h int 21h ret code ends end start
运行测试截图

实验任务4
题目描述
针对8086CPU,已知逻辑段定义如下:
data segment str db "assembly language, it's not difficult but tedious" len equ $ - str data ends
编写8086汇编源程序task4.asm,将data段中字符串里的小写字符转换成大写。
要求:
- 编写子程序
strupr- 功能:将包含任意字符的字符串中的小写字母变成大写
- 入口参数
- (
ds:si) 字符串首地址的段地址和偏移地址分别送至ds和si - (
cx) 字符串的长度
- (
- 出口参数:无
- 在主体代码中,设置入口参数,调用strupr, 实现题目要求。
代码:
1 assume cs:code,ds:data 2 data segment 3 str db "assembly language, it's not difficult but tedious" 4 len equ $ - str 5 data ends 6 7 stack segment 8 db 8 dup(?) 9 stack ends 10 11 code segment 12 start: 13 mov ax, data 14 mov ds, ax 15 mov si, 0 16 mov cx, len ; 参数:字符串长度存在cx中 17 call strupr ; 调用转换子程序 18 call printStr ; 调用打印子程序 19 20 mov ax, 4c00h 21 int 21h 22 23 strupr: 24 push cx 25 push si ; 先保存两个寄存器的值 26 transform: 27 mov al, ds:[si] ; 取出一个字符 28 cmp al, 97 ; 判断ASCII码是否 >= 97 29 jl continue ; 小于97直接进入下次循环 30 cmp al, 122 ; 判断ASCII码是否 <= 122 31 jg continue ; 大于122直接进入下次循环 32 and al, 0dfh ; 小写转成大写,原理详见实验2 33 mov ds:[si], al ; 把转换后的字符送回data段 34 continue: 35 inc si ; 指针后移 36 loop transform ; 循环 37 38 pop si 39 pop cx ; 恢复寄存器的值 40 ret ; 返回 41 42 printStr: 43 push cx ; 保存寄存器的值 44 push si 45 46 print: ; 打印字符循环 47 mov ah, 2 48 mov dl, ds:[si] 49 int 21h 50 inc si 51 loop print 52 53 pop si ; 恢复寄存器的值 54 pop cx 55 ret ; 返回 56 57 code ends 58 end start
实验结果
可以看到,该程序成功将小写字母转成了大写。

实验任务5
源代码
assume cs:code, ds:data data segment str1 db "yes", '$' str2 db "no", '$' data ends code segment start: mov ax, data mov ds, ax mov ah, 1 int 21h mov ah, 2 mov bh, 0 mov dh, 24 mov dl, 70 int 10h cmp al, '7' je s1 mov ah, 9 mov dx, offset str2 int 21h jmp over s1: mov ah, 9 mov dx, offset str1 int 21h over: mov ah, 4ch int 21h code ends end start
运行结果
输入7后,屏幕上右下角显示yes

输入其它字符,屏幕上倒数第2行右下角显示no

实验任务6
通过编译连接运行task6_1.asm和task6_2.asm后可以看到,屏幕底部出现了绿色的"welcome to 2049!",说明42号中断程序被成功调用。


浙公网安备 33010602011771号