实验任务1
<task4_1.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 si, 2
add di, 2
你的结论的依据/理由是什么?
不能替换,add指令会改变CF位的值,会干扰循环中adc指令的计算
② 在debug中调试,观察数据段中做128位加之前,和,加之后,数据段的值的变化。
加之前:
加之后:
实验任务2
<task4_2.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
运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果:
结合运行结果,理解代码并回答问题:
① 汇编指令代码line11-18,实现的功能是?
从键盘接收字符送往data段,直到遇到“#”,停止接收
② 汇编指令代码line20-22,实现的功能是?
输出一个换行符
③ 汇编指令代码line24-30,实现的功能是?
将data段的内容输出显示在屏幕上
实验任务3
<task4_3.asm>
1 assume cs:code,ds:data 2 data segment 3 x dw 91, 792, 8536, 65521, 2021 ;10个字节 4 len equ $ - x 5 data ends 6 7 code segment 8 start: 9 mov ax,data 10 mov ds,ax 11 mov bx,0 12 mov cx,len/2 13 s: call printNumber 14 call printSpace 15 add bx,2 16 loop s 17 mov ax,4c00h 18 int 21h 19 printNumber: 20 push ax 21 push bx 22 push cx 23 push dx 24 25 mov si,0 ;记录位数 26 ;经过调试发现,若直接mov ax,ds:[bx],ax高位存放的是代表十六进制数的H,最后除法的时候会有问题 27 ;mov ah,0 28 ;mov al,ds:[bx] ;低位放真正的被除数 29 mov ax,ds:[bx] 30 convert: 31 mov dx,0 ;被除数高位置0,防止干扰 32 mov cx,10 ;除数 33 div cx 34 35 add dx,30h ;余数转为字符 36 push dx ;分离出的字符暂时保存到栈;堆栈操作是以字为单位 37 38 inc si 39 mov cx,ax ;商为0结束 40 jcxz back 41 jmp convert 42 back: 43 mov cx,si 44 s1: 45 pop bx 46 mov ah,2 47 mov dl,bl 48 int 21h 49 loop s1 50 51 pop dx 52 pop cx 53 pop bx 54 pop ax 55 ret 56 printSpace: 57 mov ah,2 58 mov dl,32 59 int 21h 60 ret 61 code ends 62 end start
测试结果:
实验任务4
<task4_4.asm>
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 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov si, offset str ;offset取的是偏移地址!不是段地址! 12 mov cx, len 13 call strupr 14 mov ax, 4c00h 15 int 21h 16 strupr: 17 push si 18 push ax 19 20 s: mov al,ds:[si] 21 cmp al,61h ;大于a 22 jae check 23 inc si 24 loop s 25 check: 26 cmp al,7ah ;小于z 27 jbe ok 28 inc si 29 loop s 30 ok: 31 and al, 0dfh 32 mov ds:[si], al 33 inc si 34 loop s 35 36 pop ax 37 pop si 38 ret 39 code ends 40 end start
call strupr调用前,后:
实验任务5:
<task4_5.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 ;DOS系统功能调用int 21h的1号子功能,从键盘输入一个字符 14 int 21h 15 16 mov ah, 2 ;BIOS中断例程int 10h的2号子功能:设置光标位置 17 mov bh, 0 ;页号 18 mov dh, 24 ;行号 19 mov dl, 70 ;列号 20 int 10h 21 22 cmp al, '7' 23 je s1 ;如果输入字符等于'7',跳转到s1 24 mov ah, 9 ;DOS系统调用int 21h的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',则在指定页、行、列位置输出'yes',否则输出'no'
实验任务6
测试结果:
8086CPU软中断实现机制:
1、根据中断信息获取中断类型码
2、标志寄存器入栈,令TF=0、IF=0,以防止执行中断处理程序的时候发生单步中断
3、CS、IP依次入栈(下划线部分是为了执行完中断处理程序后恢复CPU现场)
4、根据中断类型码(N)在中断向量表中找到相应中断处理程序的入口地址
(CS=4N+2,IP=4N)
5、执行中断处理程序
6、返回
(在自定义中断处理程序时,若存在数据段,则数据段也应该放在中断程序段内部,防止程序结束后,数据段内容被其他信息覆盖,使程序结果与预期不符)