实验4 8086标志寄存器及中断
四、实验结论
1.实验任务1
- task1.asm源码
1 assume cs:code, ds:data 2 3 data segment 4 x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h 5 y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h 6 data ends 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov si, offset x 12 mov di, offset y 13 call add128 14 15 mov ah, 4ch 16 int 21h 17 18 add128: 19 push ax 20 push cx 21 push si 22 push di 23 24 sub ax, ax 25 26 mov cx, 8 27 s: mov ax, [si] 28 adc ax, [di] 29 mov [si], ax 30 31 inc si 32 inc si 33 inc di 34 inc di 35 loop s 36 37 pop di 38 pop si 39 pop cx 40 pop ax 41 ret 42 code ends 43 end start
- 回答问题
在本题中line31~line34的4条inc指令能替换成add指令。
由于task1.asm中的两个128位数相加时没有产生进位,并且也没有出现运算结果为0的情况。故将inc指令替换成相应的add指令不会影响计算结果和标志寄存器中标志位ZF、CF的值。
但在一些使用add指令会产生进位和结果为0 的情况,必须使用inc指令,否则将影响计算结果。
inc指令的调试过程
add指令的调试过程
- 调试观察截图如下所示
由图可知,数据段中做128位加之前,存放的是两个128位数。在加之后,原来存放第一个128位数的空间,现在存放的是原来两个128位数之和。
2.实验任务2
- task2.asm源码
1 assume cs:code, ds:data 2 data segment 3 str db 80 dup(?) 4 data ends 5 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax 10 mov si, 0 11 s1: 12 mov ah, 1 13 int 21h 14 mov [si], al 15 cmp al, '#' 16 je next 17 inc si 18 jmp s1 19 next: 20 mov ah, 2 21 mov dl, 0ah 22 int 21h 23 24 mov cx, si 25 mov si, 0 26 s2: mov ah, 2 27 mov dl, [si] 28 int 21h 29 inc si 30 loop s2 31 32 mov ah, 4ch 33 int 21h 34 code ends 35 end start
- 运行测试截图
- 回答问题
①汇编指令代码line11-18,实现的功能是调用int 21h的1号子功能,将从键盘输入的字符串中各字符依次存放到data数据段中,直至输入的字符为'#',通过je指令跳转到next标号,结束对字符的读入。
②汇编指令代码line20-22,实现的功能是调用int 21h的2号子功能,输出换行符到屏幕上。(0ah为换行符的ASCII码值)
③汇编指令代码line24-30,实现的功能是调用int 21h的2号子功能,循环依次打印之前输入的字符(不包括'#')。
3.实验任务3
- task3.asm源码
1 assume cs:code, ds:data, ss:stack 2 3 data segment 4 x dw 91, 792, 8536, 65521, 2021 5 len equ $ - x 6 data ends 7 8 stack segment 9 dw 8 dup(0) 10 stack ends 11 12 code segment 13 start: 14 mov ax, data 15 mov ds, ax 16 mov ax, stacksg 17 mov ss, ax 18 mov sp, 16 19 20 mov cx, len/2 ;双字,长度为一半 21 mov si, offset x 22 s: 23 mov ax, word ptr ds:[si] 24 call printNumber 25 call printSpace 26 add si, 2 27 loop s 28 29 mov ah, 4ch 30 int 21h 31 32 ;以十进制形式输出一个任意位数的整数(整数范围0~65535) 33 printNumber: 34 push cx 35 mov bx, 10 ;除数 36 mov di, 0 37 38 count: 39 mov dx, 0 40 div bx 41 push dx ;余数 42 inc di ;整数的位数 43 cmp ax, 0 ;商为0结束循环 44 je s0 45 jmp count 46 47 s0: mov ah, 2 48 mov cx, di 49 print: 50 pop dx 51 or dl, 30h ;将数字转换成对应字符 52 int 21h 53 loop print 54 55 pop cx 56 ret 57 58 ;打印一个空格 59 printSpace: 60 mov ah, 2 61 mov dl, ' ' 62 int 21h 63 ret 64 65 code ends 66 end start
- 运行测试截图
4.实验任务4
- task4.asm源码
1 assume cs:code, ds:data, ss:stack 2 3 data segment 4 str db "assembly language, it's not difficult but tedious" 5 len equ $ - str 6 data ends 7 8 stack segment 9 db 16 dup(0) 10 stack ends 11 12 code segment 13 start: 14 mov ax, data 15 mov ds, ax 16 17 mov cx, len 18 mov si, 0 19 call strupr 20 21 mov ah, 4ch 22 int 21h 23 24 strupr: 25 push cx 26 push si 27 28 s: 29 mov dl, ds:[si] 30 ;小写字母的ASCII码 97~122 31 cmp dl, 97 32 jl next ;用于有符号数,小于时跳过 33 cmp dl, 122 34 jg next ;用于有符号数,大于时跳过 35 and dl, 0dfh ;小写字母转化为大写字母 36 mov ds:[si], dl 37 38 next: 39 inc si 40 loop s 41 42 pop si 43 pop cx 44 print: 45 mov ah, 2; 46 mov dl, ds:[si] 47 int 21h 48 inc si 49 loop print 50 ret 51 52 code ends 53 end start
- 在debug中调试截图
call strupr调用之前,数据段的值
调用之后,数据段的值
5.实验任务5
- task5.asm源码
1 assume cs:code, ds:data 2 3 data segment 4 str1 db "yes", '$' 5 str2 db "no", '$' 6 data ends 7 8 code segment 9 start: 10 mov ax, data 11 mov ds, ax 12 13 mov ah, 1 14 int 21h 15 16 mov ah, 2 17 mov bh, 0 18 mov dh, 24 19 mov dl, 70 20 int 10h 21 22 cmp al, '7' 23 je s1 24 mov ah, 9 25 mov dx, offset str2 26 int 21h 27 28 jmp over 29 30 s1: mov ah, 9 31 mov dx, offset str1 32 int 21h 33 over: 34 mov ah, 4ch 35 int 21h 36 code ends 37 end start
- 程序运行测试截图
- 程序的功能是从键盘输入一个字符,判断是否为7,若为7在屏幕的第24行第70列显示yes,否则在屏幕的第24行第70列显示no。
6.实验任务6
- 汇编源程序task6_1.asm和task6_2.asm运行结果如下
中断:CPU在接收到外部发送的或内部产生的一种特殊信息时,会立即处理特殊信息。
软中断:CPU内部产生特殊信息(如除法错误、单步执行、执行into指令和执行int指令)时,立即处理该情况。
- 中断码为242(F2h),该中断例程实现的功能与实验3的实验任务5相似,能在屏幕的最后一行正中间显示学号姓名,显示为蓝底白字。
源码如下:
1 assume cs:code 2 3 code segment 4 start: 5 mov ax, cs 6 mov ds, ax 7 mov si, offset intF2 ; set ds:si 8 9 mov ax, 0 10 mov es, ax 11 mov di, 200h ; set es:di 12 13 mov cx, offset intF2_end - offset intF2 14 cld 15 rep movsb 16 17 ;设置中断向量表 18 mov ax, 0 19 mov es, ax 20 mov word ptr es:[0F2h*4], 200h 21 mov word ptr es:[0F2h*4+2], 0 22 23 mov ah, 4ch 24 int 21h 25 26 intF2: 27 jmp short intF2_start 28 stu_no db "201983290259liuxiaodie" 29 len = $ - stu_no 30 31 intF2_start: 32 mov ax, cs 33 mov ds, ax 34 mov si, 202h 35 36 mov ax, 0b800h 37 mov es, ax 38 mov di, 0 39 40 mov bl, 17h ;蓝底白字 41 call printColor 42 call printLine 43 call printNumber 44 call printLine 45 46 iret 47 48 ;打印背景颜色 49 printColor: 50 mov cx, 1920 ;前24行24*80 51 s0: 52 inc di 53 mov es:[di],bl 54 inc di 55 loop s0 56 ret 57 58 ;打印学号 59 printNumber: 60 mov cx, len ;从符号x开始的连续字节数据项个数 61 s1: 62 mov al, ds:[si] 63 mov es:[di], al 64 inc di 65 mov es:[di], bl 66 inc si 67 inc di 68 loop s1 69 ret 70 71 ;打印29个'-' 72 printLine: 73 mov cx, 29 74 s2: 75 mov word ptr es:[di], '-' 76 inc di 77 mov es:[di], bl 78 inc di 79 loop s2 80 ret 81 82 intF2_end: 83 nop 84 code ends 85 end start
1 assume cs:code 2 3 code segment 4 start: 5 int 242 6 7 mov ah, 4ch 8 int 21h 9 code ends 10 end start
运行结果如下:
五、实验总结(选)
关于在有栈段的情况下,link时出现了warning L4021: no stack segment的警告,可参考如下博客解决问题。