实验4 8086标志寄存器及中断
实验1
【源码】
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 add si,2 31 add di,2 32 33 34 loop s 35 36 pop di 37 pop si 38 pop cx 39 pop ax 40 ret 41 code ends 42 end start
1.
不可以,因为add指令会改变标志寄存器的值
2.

前两行在加前保存了两个数据段的值,加后结果保存在了前者。
实验2
【源码】
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

效果是以#号作为结束符,输出前面的所有内容
11-18行,用cmp比较输入字母,je表示当等于“#”时跳转到输出函数结束循环,否则继续循环读入内容
20-22行起换行功能,效果同实验三任务1
24-30行是对前面读入的内容进行输出。si先记录了字符串长度,赋值给cx作为循环次数。
任务3
【源码】
1 assume ds:data, cs:code 2 3 data segment 4 x dw 91, 792, 8536, 65535, 2021 5 len equ $ - x 6 data ends 7 8 code segment 9 start: 10 mov ax, data 11 mov ds, ax 12 mov si,offset x ; 取符号x对应的偏移地址0 -> si 13 mov cx,len/2 ;从符号x开始的连续字节数据项个数的一半 -> cx 14 15 s: 16 mov ax,ds:[si] 17 inc si 18 inc si 19 20 push cx ;cx入栈防止计数器冲突 21 22 call printNumber 23 call printSpace 24 25 pop cx 26 loop s 27 28 mov ah, 4ch 29 int 21h 30 31 printNumber: 32 mov bx, 0 ;入栈计数器 33 34 s1: 35 mov di, 10 36 mov dx, 0 ;dx置0 37 div di 38 39 push dx 40 inc bx 41 42 cmp ax,0 ;检测商是否为0 43 jne s1 ;不等于则转移 44 45 46 mov cx, bx 47 48 49 s2: ;输出数字 50 pop dx 51 add dl,30h 52 mov ah, 2 53 int 21h 54 loop s2 55 ret 56 57 58 printSpace: ;输出空格和上次实验一样 59 mov ah, 2 60 mov dl, 20h 61 int 21h 62 ret 63 64 code ends 65 end start

任务4
【源码】
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,offset str ; 取符号str对应的偏移地址0 -> si 16 mov cx,len ;从符号str开始的连续字节数据项个数 -> cx 17 18 call strupr 19 call printStr 20 21 mov ax, 4c00h 22 int 21h 23 24 25 strupr: 26 push cx ;cx入栈防止冲突 27 push si 28 capital: 29 mov al, ds:[si] 30 cmp al, 97 ;与a的ascii码比较 31 jb continue ;小于则跳转 32 cmp al, 122 33 ja continue 34 and al, 0dfh ;转换大写 35 mov ds:[si], al 36 continue: 37 inc si 38 loop capital 39 40 pop si 41 pop cx 42 ret 43 44 45 printStr: 46 push cx 47 push si 48 49 print: 50 mov ah, 2 51 mov dl, ds:[si] 52 int 21h 53 inc si 54 loop print 55 56 pop si 57 pop cx 58 ret 59 60 code ends 61 end start

任务5
【源码】
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则第24行第70列处输出yes,否则输出no;
如果输入的是个字母,那么会在第24行第70列处输出no
每次输入后需要使用cls清屏,否则直接在右侧输出了容易搞错。
代码中用dh和dl定义了输出的行数和列数

不然容易把自己搞不会了
任务6

中断可以在发生除法的错误、单步执行、执行into或int指令时产生和马上处理
也就解释了为什么int 21h能有中断作用
总结:
这次实验复习到很多之前的知识,如果出栈入栈时候遵循后入先出原则;
也复习到了加法和除法的规则
add al,xx,结果保存在al中
加法时需要考虑cf寄存器
通过32除16位除法解决了较大数字的输出
同时也在https://blog.csdn.net/Fgoodboy/article/details/109067736看到了一种32位无溢出的除法方法
实验五使我的读代码能力得到了训练,同时也根据运行结果对代码内容进行理解和验证
实验六摸了()

浙公网安备 33010602011771号