标志位的符号表示
取自课件
实验任务1
源代码
assume cs:code, ds:data
data segment
x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, offset x
mov di, offset y
call add128
mov ah, 4ch
int 21h
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
code ends
end start
问题
不可以,第28行中调用的指令是adc
,这个指令会在将两个操作数相加的同时,加上进位标识符CF
中的值。出于这种目的,如果在给si
、di
进行运算时,改变了进位运算符的值,就会导致运算结果出错。
调试
运行前
运行后
实验任务2
源代码
assume cs:code, ds:data
data segment
str db 80 dup(?)
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, 0
s1:
mov ah, 1
int 21h
mov [si], al
cmp al, '#'
je next
inc si
jmp s1
next:
mov ah, 2
mov dl, 0ah
int 21h
mov cx, si
mov si, 0
s2: mov ah, 2
mov dl, [si]
int 21h
inc si
loop s2
mov ah, 4ch
int 21h
code ends
end start
调试
问题
问题1
利用int 21h
的1号子功能,读入一个字符,放在数据段中偏移地址为si
的字节处,然后将其与#作比较,如果两者相等(对应着影响到标志位ZF
),就跳转到next
处运行,否则自加一继续读入字符。
问题2
利用int 21h
的2号子功能,根据dl
中的十六进制的ASCII码,打印一个字符。这里打印的是换行。
问题3
首先根据代码段s1
处对读入字符的计数,判定要输出的字符的个数,放到cx
中以决定循环要执行的次数。将si
置0,从数据段开始处进行处理。首先,设置int 21h
的2号子功能。然后读入偏移地址处的一个字节型字符,将其输出。最后让si
自加一,再次循环。
实验任务3
源代码
assume cs:code, ds:data, ss:stack
data segment
x dw 91, 792, 8536, 65521, 2021
len equ $ - x
data ends
stack segment
db 16 dup(' ')
stack ends
code segment
start:
;data
mov ax, data
mov ds, ax
;stack
mov ax, stack
mov ss, ax
mov sp, 16
mov si, 0
mov cx, 5
s: mov ax, [si]
mov di, 0
call printNumber
call printSpace
inc si
inc si
loop s
mov ah, 4ch
int 21h
printNumber:
mov dx, 0
mov bx, 10
div bx
cmp ax, 0
je s1
or dl, 30h
push dx
inc di
jmp printNumber
s1: mov bx, cx
or dl, 30h
push dx
inc di
mov cx, di
s2: pop dx
mov ah, 2
int 21h
loop s2
mov cx, bx
ret
printSpace:
mov ah, 2
mov dl, ' '
int 21h
ret
code ends
end start
注意点:
-
len
的长度是x的字节数,这里偷懒就直接用5代替len
了 -
printNumber
读取结束准备输出之前要把数据压进栈
调试
实验任务4
源代码
assume cs:code, ds:data, ss:stack
data segment
str db "assembly language, it's not difficult but tedious"
len equ $ - str
data ends
stack segment
db len dup(' ')
code segment
start:
mov ax, data
mov ds, ax
mov si, 0
mov cx, len
call strupr
mov ah, 4ch
int 21h
strupr:
s0: mov dl, [si]
cmp dl, 'a'
jae toUpper
s: mov ah, 2
int 21h
inc si
loop s0
ret
toUpper:
and dl, 0dfh
jmp s
code ends
end start
这里没有用到stack
段
调试
实验任务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
,否则输出no
。
实验任务6
对中断的理解
进程的基本状态有就绪、运行、阻塞,在我看来,中断应该就是导致程序进入阻塞状态的原因之一。当遇到阻塞时,系统会保存运行环境,转而去运行另外的程序。int 21h
的4c
子功能表示该程序运行结束,进入就绪状态,这时导致阻塞的原因即中断去转而实现的程序也运行结束,那么原来的程序就可以继续运行。在此看来,中断程序就是一种程序,当他被唤起时,就会立即占用处理器的资源,直到自己运行结束归还资源。