实验6(p160)、实验7(p173)、实验9(p189)、实验10(p206,p208, p209)、实验11(p234)、实验12(p251)、p256(编写7cH中断例程完成loop指令功能)、实验13(p262)、实验14(p271)、实验15(p285)


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验6(p160)

; DATE: 20190608
; DESCRIPTION: 每个单词的前4个字母改为大写assume cs:code, ds:data, ss:stackstack segmentdw 0, 0, 0, 0, 0, 0, 0, 0 ; 定义一个段,16Bytes,用作栈段
stack endsdata segmentdb '1. display      'db '2. brows        'db '3. replace      'db '4. modify       '
data endscode segment
start:mov ax, stackmov ss, axmov sp, 16mov ax, datamov ds, axmov bx, 0mov cx, 4
line:push cx             ; 将外层循环的计数值cx入栈mov cx, 4mov si, 0           ; cx设置为内层循环的次数
toBig:mov al, [bx+si+3]and al, 11011111Bmov [bx+si+3], alinc siloop toBigadd bx, 16pop cx              ; 出栈,恢复外层循环的计数值loop line           ; loop指令将cx中的计数值减1mov ax, 4c00Hint 21H
code ends
end start

运行结果:

# before

# after


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验7(p173)

; DATE: 20190608
; DESCRIPTION: 实验7(p173)assume cs:codedata segmentdb '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983'db '1984', '1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992'db '1993', '1994', '1995'dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97497, 140417, 197514dd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000dw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226dw 11542, 14430, 15257, 17800
data endstable segmentdb 21 dup ('year summ ne ?? ')
table endscode segment
start:mov ax, datamov es, axmov si, 0mov di, 168         ; di指向data中的雇员mov ax, tablemov ds, axmov bx, 0mov cx, 21          ; 21年,循环21次
year:; 年份mov ax, es:[si]     ; si指向data中的年份mov [bx], ax        ; bx指向tablemov ax, es:[si+2]mov [bx+2], ax; 收入mov ax, es:[si+84]  ; si+84指向data中的收入mov [bx+5], axmov ax, es:[si+86]mov [bx+7], ax; 雇员mov ax, es:[di]mov [bx+0aH], ax; 人均收入mov ax, [bx+5]      ; ax存放被除数低16位mov dx, [bx+7]      ; dx存放被除数高16位div word ptr [bx+0aH]mov [bx+0dH], ax    ; 结果的商存放在ax中add bx, 10Hadd si, 4 add di, 2loop yearmov ax, 4c00Hint 21H
code ends
end start

运行结果:

# before

# after


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验9(p189)

# 草稿版

; DATE: 20190609
; DESCRIPTION: 在屏幕中间分别显示绿色、绿底红色、白底蓝色的
;       字符串'welcome to masm!'assume cs:code, ds:data, ss:stackdata segmentdb 'welcome to masm!'   ; 16Bytes
data endscode segment
start:mov ax, datamov ds, axmov bx, 0mov ax, 0B800Hmov es, axmov si, 160*11+64       ; 定位到屏幕中间mov cx, 16
write:    mov al, [bx]mov ah, 01110001B       ; 白底蓝字mov es:[si], axinc bxadd si, 2loop writemov ax, 4c00Hint 21H
code ends
end start

# 运行结果

# 完善版

; DATE: 20190609
; DESCRIPTION: 在屏幕中间分别显示绿色、绿底红色、白底蓝色的
;       字符串'welcome to masm!'assume cs:code, ds:datadata segmentdb 'welcome to masm!'   ; 16Bytesdb 02H, 24H, 71H        ; 颜色属性:绿色、绿底红色、白底蓝色
data endsstack segmentdb 16 dup (0)
stack endscode segment
start:mov ax, datamov ds, axmov bx, 0               ; ds:bx 数据段mov di, 16              ; ds:di 颜色属性 mov ax, stackmov ss, axmov sp, 16              ; ss:sp 栈空间mov ax, 0B800Hmov es, axmov si, 160*11+64       ; es:si 定位到屏幕中间区域mov cx, 3               ; 3行
line:push cxpush simov cx, 16              ; 每行16个字符
write: mov al, [bx]            ; 字符mov ah, [di]            ; 颜色属性mov es:[si], axinc bxadd si, 2loop writemov bx, 0               ; ds:bx 重新指向第一个字符inc di                  ; ds:di 指向下一个颜色属性pop siadd si, 160             ; es:si 指向下一行pop cxloop linemov ax, 4c00Hint 21H
code ends
end start

# 运行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验10-1(p206)

; DATE: 20190611
; DESCRIPTION: 显示字符串assume cs:codedata segmentdb 'welcome to masm!', 0
data endscode segment
start:mov dh, 8   ; 第8行mov dl, 3   ; 第3列mov cl, 2   ; 绿色mov ax, datamov ds, axmov si, 0   ; ds:si指向data段call show_strmov ax, 4c00Hint 21H; 名称:show_str
; 功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串
; 参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79)
;       (cl)=颜色, ds:si指向字符串首地址
; 返回:无
show_str:push dxpush cxpush simov ax, 0b800Hmov es, ax      ; 显示缓冲区 b8000 ~ b8ffffmov al, 160     ; 一行80个字符,加上颜色属性,占160Bytesmul dhmov di, ax mov al, 2mul dladd di, ax      ; es:di指向屏幕指定位置对应的显示缓冲区mov ah, cl      ; 高位字节存储颜色属性
s0:mov ch, 0mov cl, [si]    ; 给定的字符串以0结尾jcxz okmov al, cl      ; 低位字节存储字符ASCII码mov es:[di], axinc siadd di, 2jmp short s0
ok:pop sipop cxpop dxretcode ends
end start

# 运行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验10-2(p208)

; DATE: 20190613
; DESCRIPTION: 不会产生溢出的除法assume cs:codecode segment
start:mov ax, 4240Hmov dx, 000fHmov cx, 0aHcall divdw; 名称:divdw
; 功能:不会产生溢出的除法,被除数为dword,除数为word,结果为dword
; 参数:(ax)=dword低16位 (dx)=dword高16位 (cx)=除数
; 返回:(dx)=结果高16位 (ax)=结果低16位 (cx)=余数
divdw:push ax     ; 被除数低16位; 被除数的高16位除法mov ax, dxmov dx, 0div cx; 被除数的低16位除法mov bx, ax  ; 高16位除法的商暂移到bxpop axdiv cx; 结果返回mov cx, dx  ; 低16位除法的余数移到cxmov dx, bx  ; 高16位除法的商移到dxmov ax, 4c00Hint 21H
code ends
end start

# 运行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验10-3(p209)

; DATE: 20190613
; DESCRIPTION: 十进制数转为字符串assume cs:codedata segmentdb 10 dup (0)
data endscode segment
start:mov ax, 12666mov bx, datamov ds, bxmov si, 0call dtocmov dh, 8mov dl, 3mov cl, 2call show_strmov ax, 4c00Hint 21H; 名称:dtoc
; 功能:将word型数据转变为表示十进制数的字符串,以0结尾
; 参数:(ax)=word型数据,ds:si指向字符串的首地址
; 返回:无
dtoc:push axpush cxpush dx push simov bx, 10
change:mov dx, 0       ; 被除数的高16位div bxadd dx, 30H     ; dx为余数,转为字符push dx         ; 余数入栈inc si          ; 通过si统计长度mov cx, ax      ; ax为商jcxz savejmp short change
save:mov cx, simov si, 0
s1:pop [si]        ; 余数出栈,保存到ds:siinc si          ; 取巧,出栈2Bytes,但si+1;末尾以0结尾loop s1pop sipop dxpop cxpop axret; 名称:show_str
; 功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串
; 参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79)
;       (cl)=颜色, ds:si指向字符串首地址
; 返回:无
show_str:push dxpush cxpush simov ax, 0b800Hmov es, ax      ; 显示缓冲区 b8000 ~ b8ffffmov al, 160     ; 一行80个字符,加上颜色属性,占160Bytesmul dhmov di, ax mov al, 2mul dladd di, ax      ; es:di指向屏幕指定位置对应的显示缓冲区mov ah, cl      ; 高位字节存储颜色属性
s0:mov ch, 0mov cl, [si]    ; 给定的字符串以0结尾jcxz okmov al, cl      ; 低位字节存储字符ASCII码mov es:[di], axinc siadd di, 2jmp short s0
ok:pop sipop cxpop dxretcode ends
end start

# 运行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验11(p234)

assume cs:code
data segmentdb "Beginner's All-purpose Symbolic Instruction Code.",0
data endscode segment
begin:mov ax, datamov ds, axmov si, 0call lettercmov ax, 4c00Hint 21H; 名称:letterc
; 功能:将以0结尾的字符串中的小写字母转为大写
; 参数:ds:si指向字符串首地址
; 返回:无
letterc:push cxpush si     ; 保护现场mov ch, 0
change:mov cl, [si]jcxz okcmp cl, 'a'jb nextcmp cl, 'z'ja nextand cl, 11011111B ; 为小写字母则减32mov [si], cl
next:inc sijmp short change
ok:pop sipop cx      ; 恢复现场retcode ends
end begin

# 运行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验12(p251)

; DATE: 20190618
; DESCRIPTION: 编写0号中断处理程序,使得在除法溢出发生时,
;       在屏幕上显示字符串"divide error!",然后回到DOSassume cs:codecode segment
start:mov ax, csmov ds, axmov si, offset do0  ; ds:si指向源地址,处理程序所在mov ax, 0mov es, axmov di, 0200H       ; es:di指向目的地址mov cx, offset do0end - offset do0 ; 设置cx为传输长度cld                 ; 设置DF标志位为0,即传输方向为正rep movsb           ; 将ds:si中的字节送入es:dimov ax, 0mov es, ax          ; 设置中断向量表中除法错误即mov word ptr es:[0*4], 0200H    ; 0号中断对应的处理程序入口地址mov word ptr es:[0*4+2], 0      ; 我们选用0000:0200~0000:02ff这段内存空间mov ax, 4c00Hint 21Hdo0:jmp short do0startdb "divide error!"  ; 提示信息
do0start:push axpush cxpush dspush espush dipush si             ; 保护现场mov ax, csmov ds, axmov si, 0202H       ; ds:si指向字符串mov ax, 0b800Hmov es, axmov di, 12*160+36*2 ; es:di指向屏幕中间位置对应的显存空间mov cx, 13          ; 字符串长度为13mov ah, 71H         ; 颜色属性,白底蓝字
s:mov al, [si]mov es:[di], axinc siadd di, 2loop s              ; 将字符串复制到显存空间pop sipop dipop espop dspop cxpop ax              ; 恢复现场mov ax, 4c00Hint 21H
do0end:                 ; 标记结束位置,用于前面计算处理程序的长度nopcode ends
end start

# 除法溢出的测试代码

; DATE: 20190618
; DESCRIPTION: 除法溢出的测试代码assume cs:code
code segment
start:mov ax, 1000Hmov bh, 1div bhmov ax, 4c00Hint 21H
code ends
end start

# 运行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

p256(编写7cH中断例程完成loop指令功能)

; DATE: 20190620
; DESCRIPTION: 编写7cH中断例程完成loop指令功能assume cs:codecode segment
start:mov ax, csmov ds, axmov si, offset myloop   ; ds:si指向源地址mov ax, 0mov es, axmov di, 0200H           ; es:di指向目的地址mov cx, offset myloopend - offset myloop ; 设置cx为传输长度cld                     ; 设置DF标志位为0,即传输方向为正rep movsb               ; 将ds:si中的字节送入es:dimov ax, 0mov es, axmov word ptr es:[7cH*4], 0200Hmov word ptr es:[7cH*4+2], 0 ; 设置中断向量表mov ax, 4c00Hint 21Hmyloop:; 使用寄存器间接寻址时,只可以使用 BX,BP,SI,DI这四个寄存器; 中断过程中,当前的标志寄存器、CS和IP都要入栈push bpmov bp, spdec cxjcxz myloopretsub [bp+2], bx ; 修改进入中断时的IP值
myloopret:pop bpiret
myloopend:nopcode ends
end start

p256-2(调用编写的7cH中断例程所实现的loop功能,在屏幕中间显示80个‘!’)

; DATE: 20190620
; DESCRIPTION: 编写7cH中断例程完成loop指令功能
;       在屏幕中间显示80个'!'assume cs:codecode segment
start:mov ax, 0b800Hmov es, axmov di, 160*12mov bx, offset send - offset smov cx, 80;mov ah, 71H;mov al, '!'
s:;mov es:[di], axmov byte ptr es:[di], '!'add di, 2;loop sint 7cH
send:nopmov ax, 4c00Hint 21H
code ends
end start

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验13-1(p262)

# 安装中断例程

; DATE: 20190620
; DESCRIPTION: 编写并安装7cH中断例程
;   功能为显示一个用0结束的字符串
assume cs:codecode segmentmov ax, csmov ds, axmov si, offset show     ; ds:simov ax, 0mov es, axmov di, 0200H           ; es:dimov cx, offset showend - offset showcldrep movsb               ; 复制mov ax, 0mov es, axmov word ptr es:[7cH*4], 0200Hmov word ptr es:[7cH*4+2], 0 ; 设置中断向量表mov ax, 4c00Hint 21H; 名称:show
; 功能:显示一个用0结束的字符串
; 参数:(dh)=行号 (dl)=列号 (cl)=颜色,ds:si指向字符串首地址
; 返回:无
show:push axpush cxpush sipush dipush es         ; 保护现场mov ax, 0b800Hmov es, ax      ; es:di指向显示缓冲区mov al, dhmov ah, 160mul ah          ; 行号*160mov di, axmov al, dlmov ah, 2mul ah          ; 列号*2add di, ax      mov ah, cl
showbegin:mov al, [si]cmp al, 0je showretmov word ptr es:[di], axinc siadd di, 2jmp short showbegin
showret:pop espop dipop sipop cxpop ax          ; 恢复现场iret
showend:nopcode ends
end

# 测试中断例程

; DATE: 20190620
; DESCRIPTION: 调用自定义的7cH中断例程
;   显示一个用0结束的字符串assume cs:codedata segmentdb "Welcome to masm!", 0
data endscode segment
start:mov dh, 10mov dl, 10mov cl, 2mov ax, datamov ds, axmov si, 0; 参数:(dh)=行号 (dl)=列号 (cl)=颜色; ds:si指向字符串首地址int 7cHmov ax, 4c00Hint 21H
code ends
end start

# 执行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验13-2(p263)

# 安装中断例程

; DATE: 20190620
; DESCRIPTION: 编写并安装7cH中断例程
;   功能为完成loop指令功能
assume cs:codecode segmentmov ax, csmov ds, axmov si, offset myloop   ; ds:simov ax, 0mov es, axmov di, 0200H           ; es:dimov cx, offset myloopend - offset myloopcldrep movsb               ; 安装中断例程mov ax, 0mov es, axmov word ptr es:[7cH*4], 0200Hmov word ptr es:[7cH*4+2], 0 ; 设置中断向量表mov ax, 4c00Hint 21H; 名称:myloop
; 功能:完成loop指令功能
; 参数:(cx)=循环次数 (bx)=位移
; 返回:无
myloop:push bpdec cxjcxz myloopretmov bp, spadd [bp+2], bx
myloopret:pop bpiret
myloopend:nopcode ends
end

# 测试中断例程

; DATE: 20190620
; DESCRIPTION: 调用自定义的7cH中断例程
;   在屏幕中间显示80个'!'
assume cs:code
code segmentmov ax, 0b800Hmov es, axmov di, 12*160  ; es:dimov cx, 80mov bx, offset s - offset send
s:mov byte ptr es:[di], '!'add di, 2int 7cH
send:nopmov ax, 4c00Hint 21H
code ends
end

# 执行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验13-3(p264)

; DATE: 20190620
; DESCRIPTION: 分别在屏幕第2、4、6、8行显示4句话
assume cs:codecode segment
s1: db 'Good, better, best,', '$'
s2: db 'Never let it rest,', '$'
s3: db 'Till good is better,', '$'
s4: db 'And better, best.', '$'
s : dw offset s1, offset s2, offset s3, offset s4
row: db 2,4,6,8start:mov ax, csmov ds, axmov bx, offset smov si, offset rowmov cx, 4
ok:mov bh, 0   ; 页mov dh, [si] ; 行mov dl, 0   ; 列号mov ah, 2   ; 第10H号中断例程的2号子程序:置光标int 10Hmov dx, [bx] ; ds:dx指向字符串,字符串以'$'作为结束符mov ah, 9   ; 第21H号中断例程的9号子程序:在光标位置显示字符串int 21Hinc siadd bx, 2loop okmov ax, 4c00Hint 21H
code ends
end start

# 执行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验14(p271)

# 法一:直接写入显示缓冲区

; DATE: 20190621
; DESCRIPTION: 从CMOS RAM中读取当前时间,
;       并以"年/月/日 时:分:秒"的格式显示
assume cs:code
code segment
addres: db 9,8,7,4,2,0      ; 单元的地址start:mov ax, csmov ds, axmov si, offset addresmov ax, 0b800H          ; 显示缓冲区mov es, axmov di, 12*160+35*2; 将分隔符写入显示缓冲区mov byte ptr es:[di+4], '/'mov byte ptr es:[di+10], '/'mov byte ptr es:[di+16], ' 'mov byte ptr es:[di+22], ':'mov byte ptr es:[di+28], ':'mov cx, 6
time:push cx         ; 保护循环次数mov al, [si]out 70H, al ; 将单元号送入端口70Hin al, 71H  ; 从端口71H读出该单元的内容mov ah, almov cl, 4shr ah, cl          ; 右移4位and al, 00001111B   ; 得到低字节add ah, 30H         ; 将数字转为字符add al, 30Hmov es:[di], ah     ; 写入显示缓冲区mov es:[di+2], alinc siadd di, 6pop cxloop timemov ax, 4c00Hint 21H
code ends
end start

# 执行结果

# 法二:调用DOS的第21H号中断例程的9号子程序:在光标位置显示字符串

; DATE: 20190621
; DESCRIPTION: 从CMOS RAM中读取当前时间,
;       并以"年/月/日 时:分:秒"的格式显示
assume cs:code
code segment
addres: db 9,8,7,4,2,0  ; 单元的地址
date  : db '2000/00/00 00:00:00', '$'start:mov ax, csmov ds, axmov si, offset addres   ; ds:simov di, offset date     ; ds:diadd di, 2mov cx, 6
time:push cx         ; 保护循环次数mov al, [si]out 70H, al ; 将单元号送入端口70Hin al, 71H  ; 从端口71H读出该单元的内容mov ah, almov cl, 4shr ah, cland al, 00001111Badd ah, 30Hadd al, 30Hmov [di], ah    ; 写入字符串ds:di中mov [di+1], alinc siadd di, 3pop cxloop timemov bh, 0   ; 页mov dh, 12  ; 行号mov dl, 35  ; 列号mov ah, 2   ; 第10H号中断例程的2号子程序:置光标int 10Hmov dx, offset date ; ds:dx指向字符串,字符串以'$'作为结束符mov ah, 9   ; 第21H号中断例程的9号子程序:在光标位置显示字符串int 21Hmov ax, 4c00Hint 21H
code ends
end start

# 执行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验15(p285)

; DATE: 20190622
; DESCRIPTION: 在DOS下,按'A'键后松开时显示满屏幕的‘A’,其他的键照常处理
;
; 已知:int 9为BIOS提供的一个中断例程,用来进行基本的键盘输入处理
assume cs:codestack segmentdb 128 dup (0)
stack endscode segment
start:mov ax, stackmov ss, axmov sp, 128         ; ss:sppush cspop dsmov si, offset int9 ; ds:si指向源地址mov ax, 0mov es, axmov di, 204H        ; es:di指向目的地址; 将新int 9中断例程安装在0:204开始处mov cx, offset int9end - offset int9 ; cx传输长度cld         ; 将DF标志位置0,即传输方向为正rep movsb   ; 从ds:si复制到es:di; 将原int 9中断例程的入口地址保存到0:200单元; 所以,程序二次执行将出错push es:[9*4]pop es:[200H]push es:[9*4+2]pop es:[202H]; 将新int 9中断例程的入口地址保存到中断向量表cli     ; 将IF标志位置0,不响应可屏蔽中断mov word ptr es:[9*4], 204Hmov word ptr es:[9*4+2], 0sti     ; 将IF标志位置1,响应可屏蔽中断mov ax, 4c00Hint 21Hint9:push axpush bxpush cxpush esin al, 60H  ; 从端口60H读出键盘的输入pushf       ; 标志寄存器入栈call dword ptr cs:[200H] ; 当此中断例程执行时(CS)=0cmp al, 1eH+80H ; 'A'键按下的扫描码为3bH,即通码; 松开时的断码=通码+80Hjne int9ret; 显示满屏幕的‘A’mov ax, 0b800Hmov es, axmov bx, 0mov cx, 2000
s:  mov byte ptr es:[bx], 'A'add bx, 2loop s int9ret:pop espop cxpop bxpop axiret
int9end:nop
code ends
end start

# 执行结果


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

实验16(p299)

# 安装中断例程

; DATE: 20190622
; DESCRIPTION: 安装一个新的int 7cH中断例程,提供以下功能子程序:
;   1)清屏;2)设置前景色;3)设置背景色;4)向上滚动一行
;   入口参数:ah功能号 0~3;al颜色值 0~7assume cs:codecode segment
start:mov ax, csmov ds, axmov si, offset setscreen    ; ds:si 指向源地址mov ax, 0mov es, axmov di, 200H                ; es:di 指向目的地址; 将新int 9中断例程安装在0:200开始处cld     ; 将DF标志位置0,即传输方向为正mov cx, offset setend - offset setscreen ; cx传输长度rep movsb   ; 从ds:si复制到es:di; 将新int 9中断例程的入口地址保存到中断向量表cli     ; 将IF标志位置0,不响应可屏蔽中断mov word ptr es:[7cH*4], 200Hmov word ptr es:[7cH*4+2], 0sti     ; 将IF标志位置1,响应可屏蔽中断mov ax, 4c00Hint 21H; 注意此处必须用org; 否则,将编译后的table[bx]复制到0:200H后,会指向未知位置org 200H    ; 通知编译器从200H开始重新计算标号setscreen:jmp short settable dw sub1,sub2,sub3,sub4 ; 查表,4个子程序的入口地址set:push bxcmp ah, 3   ; 判断功能号是否大于3ja sretmov bl, ahmov bh, 0add bx, bx  ; 根据ah功能号计算子程序在table中的偏移call word ptr table[bx] ; 调用对应的子程序
sret:    pop bxiret        ; 中断返回; ------ 4个子程序 ------
; ------ 子程序:清屏 ------
sub1:push bxpush cxpush esmov bx, 0b800Hmov es, bx  ; 此处使用bx节约了寄存器mov bx, 0   ; es:bx指向显示缓冲区mov cx, 2000 ; 25行*80列
sub1s:mov byte ptr es:[bx], ' 'add bx, 2loop sub1s  ; 清屏pop espop cxpop bxret; ------ 子程序:设置前景色 ------
sub2:push bxpush cxpush esmov bx, 0b800Hmov es, bxmov bx, 1   ; es:bx指向显示缓冲区mov cx, 2000
sub2s:; 高字节为颜色属性,前景色为第0、1、2位and byte ptr es:[bx], 11111000Bor es:[bx], aladd bx, 2 loop sub2spop espop cxpop bxret; ------ 子程序:设置背景色 ------
sub3:push bxpush cxpush esmov bx, 0b800Hmov es, bxmov bx, 1   ; es:bx指向显示缓冲区mov cl, 4shl al, clmov cx, 2000
sub3s:; 高字节为颜色属性,背景色为第4、5、6位and byte ptr es:[bx], 10001111Bor es:[bx], aladd bx, 2 loop sub3spop espop cxpop bxret; ------ 子程序:向上滚一行 ------
sub4:push cxpush dspush espush sipush dimov si, 0b800Hmov ds, simov es, simov si, 160     ; ds:si指向源地址mov di, 0       ; es:di指向目的地址cld     ; 将DF标志位置0,即传输方向为正mov cx, 24  ; 最后一行为空
sub4s:push cxmov cx, 160     ; 每行的传输长度为160Bytesrep movsb       ; si=si+1 di=di+1pop cxloop sub4smov cx, 160mov si, 0       ; si的默认段地址为ds
sub4s1:mov byte ptr [160*24+si], ' ' ; 最后一行清空add si, 2 loop sub4s1pop dipop sipop espop dspop cxretsetend:nopcode ends
end start

# 测试中断例程

assume cs:codecode segment
start:mov ah, 1   ; 设置前景色mov al, 1   ; 蓝色int 7cHcall delay  ; 延时mov ah, 2   ; 设置背景色mov al, 7   ; 白色int 7cHcall delaymov ah, 3   ; 向上滚一行int 7cHcall delaymov ah, 0   ; 清屏int 7cHmov ax, 4c00Hint 21H; ------ 循环延时 ------
delay:push axpush dxmov dx, 10H ; 循环20000H次,根据自己机器的速度调整循环次数mov ax, 0
s1:sub ax, 1 sbb dx, 0cmp ax, 0 jne s1 cmp dx, 0 jne s1 pop dx pop ax retcode ends
end start

# 执行结果

汇编语言-第三版-王爽-实验6、7、9、10、11、12、13、14、15相关推荐

  1. 读书笔记:汇编语言 第三版 王爽 清华出版社 前言 章一 章二 章三 章四 章五

    汇编语言 第三版 王爽 清华出版社文档记录创建 2020年8月9日15:21:11初稿完成 2020年9月5日15:38:22前言汇编语言,CPU提供的机器指令的助记符的集合不同处理器,机器指令可能不 ...

  2. 读书笔记:汇编语言 第三版 王爽 清华出版社 章十六 章十七 章十八

    第十六章 直接定址表16.1 描述了单位长度的标号地址标号,表征了位置的偏移地址label:数据标号,表征了一段内存空间的物理地址和长度,增强型地址标号段地址,数据标号所在段的关联段寄存器,assum ...

  3. 读书笔记:汇编语言 第三版 王爽 清华出版社 章六 章七 章八 章九 章十

    第六章 包含多个段的程序6.0 概述合法地通过操作系统取得的空间都是安全的操作系统不会让多个程序之间发生空间冲突程序向操作系统获得空间的方法程序加载时分配在程序中定义各种段程序运行时分配通过指令向操作 ...

  4. 汇编语言-第三版-王爽-第15章 外中断-第16章 直接定址表

    P280:在屏幕中间依次显示a~z, 显示过程中,按下ESC键后,改变显示颜色 P283:在DOS下,按F1键后改变当前屏幕的显示颜色,其他的键照常处理 P293:以十六进制的形式显示给定的字节型数据 ...

  5. 汇编语言-第三版-王爽-课程设计1

    课程设计1(p211). * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ...

  6. 汇编语言 第3版 王爽 检测点习题部分—答案及详细解析

    第一章 基础知识 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为()位. (2)1KB的存储器有() 个存储单元,存储单元的编号从()到() . (3)1KB的存储器可以存 ...

  7. 汇编语言 (第2版) 王爽 中文高清PDF版下载

    汇编语言 (第2版) 王爽 中文高清PDF版下载 转载于:https://www.cnblogs.com/gavinhughhu/archive/2009/12/10/1620783.html

  8. 汇编语言 第3版 王爽 检测点习题部分—答案及详细解析 检测点3.2

    题目(1) : 补全下面的程序,使其可以将10000H- ~1000FH 中的8个字,逆序复制到 20000H~2000FH中.逆序复制的含义如图3.17所示(图中内存里的数据均为假设). 解答: p ...

  9. 汇编语言 第3版 王爽 检测点习题部分—答案及详细解析 检测点3.1

    视频中的文本: 记录监测点3.1 两个小实验 先进行第一个实验.我们通过赋值,达到实验条件. 这种方式是可以的,那么进行下一个赋值.赋值全部完成. 第一个实验仅仅对AX BX观察以及操作. 那么不需要 ...

最新文章

  1. table列最小宽度 vue_vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)...
  2. scrapy-redis的关键配置
  3. java小程序开发平台,隔壁都馋哭了
  4. LeetCode 1797. 设计一个验证系统(map)
  5. java 向上抛异常_Java 异常的处理方式throws
  6. 阿里宣布取消的周报又死灰复燃?3分钟的高效报表才是最后出路
  7. void类型及void指针
  8. Mac OS使用ll、la、l等ls的别名命令
  9. (转载)equals与==
  10. 【重识 HTML + CSS】CSS 选择器
  11. TextView实现歌词同步《IT蓝豹》
  12. 大数据学习系列之八----- Hadoop、Spark、HBase、Hive搭建环境遇到的错误以及解决方法
  13. android开发那些事儿(二)--Drawable资源
  14. 厦门大学信息计算机学院,厦门大学信息科学与技术学院计算机科学系导师介绍:刘向荣...
  15. 红外编解码模块YS-NEC使用
  16. php网页报告2500字,教你写作文2500字
  17. C++boost库中sp_counted_impl_x实现解析
  18. python bytes与str之间的转换 hex的字符转换
  19. C语言学习(三)内存初识、数据在内存中的保存形式、程序载入内存
  20. 菜鸟的数学建模之路(二):线性与非线性回归

热门文章

  1. 《关于建立统一的城乡居民基本养老保险制度的意见》
  2. 惠普笔记本触摸板双指、多指操作失效问题的解决
  3. 北航计算机在职研究生定向,北航软件学院首招人工智能方向研究生
  4. ubuntu 解压文件
  5. 中国物流集团携手用友启动ERP暨财务共享建设项目
  6. 测绘学概论第三版——2 大地测量学
  7. 【虚幻】清理缓存文件(C盘占用过大)
  8. Python自定义高精度小数计算来获取巴塞尔问题的近似值
  9. 照片换背景怎么操作?照片换背景软件分享。
  10. 操作系统的内存管理机制(连续分配管理、页式、段式、段页式、快表、二级页表)