王爽《汇编语言》实验16——编写包含多个功能子程序的中断例程

本文介绍了一个使用MASM5编写的中断例程,该例程实现了屏幕清屏、设置前景色、设置背景色及屏幕向上滚动一行等功能。通过传递不同的功能号和颜色值,可以灵活地控制屏幕显示。

;MASM5编译通过

;==========================================================================

;安装一个新的 INT 9 中断例程,为显示输出提供如下功能子程序:

;(1)清屏;(2)设置前景色;(3)设置背景色;(4)向上滚动一行

;AH传递功能号,0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行.

;对于12号功能,AL传递颜色值,(AL){0,1,2,3,4,5,6,7}

;==========================================================================

ASSUME CS:CODE

 

CODE SEGMENT

    S1  DB "Good,better,best,",'$'

    S2  DB "Never let itrest,",'$'

    S3 DB "Till good isbetter,",'$'

    S4 DB "Andbetter,best.",'$'

    S   DW OFFSET S1,OFFSET S2,OFFSET S3,OFFSET S4

    ROW DB 2,4,6,8

 

START:

    ;安装中断处理程序到0:200H

    PUSH CS

    POP DS      ;(DS)=传送原始位置的段地址

    MOV SI,OFFSET INT7START ;DS:SI指向传送原始位置的首地址

    MOV AX,0

    MOV ES,AX   ;(ES)=0,传送目的位置的段地址

    MOV DI,200H ;ES:SI指向传送目的位置的首地址

    MOV CX,OFFSET INT7END-OFFSET INT7START ;传送长度

    CLD     ;正向

    REP MOVSB   ;传送

   

    ;设置中断向量表

    MOV WORD PTR ES:[4*7CH],200H

    MOV WORD PTR ES:[4*7CH+2],0

   

    ;测试 INT 7CH 0号子程序

    MOV AH,0

    INT 7CH

   

    ;向屏幕输出四句英文诗

    MOV AX,CS           ;DSCS使用同一段

    MOV DS,AX

    MOV BX,OFFSET S     ;BX用来寻址字符串的首地址

    MOV SI,OFFSET ROW   ;SI用来寻址行数

    MOV CX,4            ;循环次数4

   

    OK:

    MOV BH,0            ;0

    MOV DH,BYTE PTR CS:[SI] ;(DH)=行数

    MOV DL,0            ;(DL)=列数

    MOV AH,2            ;置光标

    INT 10H

   

    MOV DX,CS:[BX]  ;DS:DX指向字符串的首地址

    MOV AH,9            ;输出以"$"结尾的字符串

    INT 21H

   

    INC SI              ;SI指向下一句诗的行数

    ADD BX,2            ;BX指向下一句诗的字符串的首地址

    LOOP OK         ;输出下一句诗

   

    ;以下,测试 INT 7CH 1~3号子程序

    MOV AH,1

    MOV AL,10 

    INT 7CH

   

    MOV AH,2

    MOV AL,4

    INT 7CH

   

    MOV AH,3

    INT 7CH

   

    ;程序返回

    MOV AX,4C00H

    INT 21H

 

    ;新的 INT 9 中断例程

;-----------------------------------------------------------------------------------   

;功能:0号子程序:清屏 1号子程序:设置前景色 2号子程序:设置背景色 3号子程序:向上滚动一行

;参数:(AH)=功能选择,(AL)=颜色

;返回:

INT7 PROC NEAR

    INT7START:

    JMP SHORT INT7_REAL_START

    ;直接定址表

    TABLE DW SUB0-INT7+200H,SUB1-INT7+200H,SUB2-INT7+200H,SUB3-INT7+200H

    ;这一句执行完以后,TABLE中存放中断处理程序中各子程序的IP

    ;因为位移是在编译的时候算出来的,一定要保证这里算出来的结果和

    ;安装到0:200H处以后的结果相符

    INT7_REAL_START:

    PUSH AX     ;保护现场

    PUSH BX

    PUSH DX

    PUSH DS

    PUSH ES

   

    PUSH CS     ;进入中断处理程序前,(CS)=0,(DS)可能≠0

    POP DS          ;设置(DS)=0

   

    MOV BL,AH

    MOV BH,0

    SHL BX,1        ;(BX)=(BX)*2

    MOV DX,0B800H

    MOV ES,DX

    ;这里取得0:200H处中断处理程序子程序IP,也要按(CS)=0000考虑

    CALL WORD PTR [TABLE-INT7+200H+BX] ;(DS)=0,DS:[TABLE-INT7+200H+BX]存放着

                                        ;中断处理程序被安装0:200H处后子程序的IP

    JMP INT7RET    

   

    SUB0:           ;0号子程序,清屏

    PUSH CX

    PUSH DI

   

    ;把屏幕上的所有字符替换成空格

    MOV DI,0

    MOV CX,2000

    SUB0S:

    MOV BYTE PTR ES:[DI],' ' 

    INC DI

    INC DI

    LOOP SUB0S

   

    POP DI

    POP CX

    RET

   

    SUB1:           ;1号子程序,改变前景色

    PUSH CX

    PUSH DI

   

    ;修改显示缓冲区所有字符属性字节的值

    MOV DI,1

    MOV CX,2000

    SUB1S:

    AND BYTE PTR ES:[DI],11111000B

    OR ES:[DI],AL

    INC DI

    INC DI

    LOOP SUB1S

   

    POP DI

    POP CX

    RET

   

    SUB2:           ;2号子程序,改变背景色

    PUSH AX

    PUSH CX

    PUSH DI

   

    ;修改显示缓冲区所有字符属性字节的值

    MOV CL,4

    SHL AL,CL

    MOV DI,1

    MOV CX,2000

    SUB2S:

    AND BYTE PTR ES:[DI],10001111B

    OR ES:[DI],AL

    INC DI

    INC DI

    LOOP SUB2S

   

    POP DI

    POP CX

    POP AX

    RET

   

    SUB3:           ;3号子程序,上卷一行

    PUSH CX

    PUSH SI

    PUSH DI

    PUSH DS

   

    PUSH ES

    POP DS          ;设置(ES)=(DS)=显示缓冲区段地址

    MOV SI,160      ;DS:SI指向传送原始位置的首地址

    MOV DI,0        ;ES:SI指向传送目的位置的首地址

    MOV CX,24*160   ;传送长度

    REP MOVSB       ;传送

    MOV DI,24*160   ;最后一行的偏移地址 

    MOV CX,160      ;传送长度

    SUB3S:          ;用空格代替

    MOV BYTE PTR ES:[DI],' '

    INC DI

    INC DI

    LOOP SUB3S

   

    POP DS

    POP DI

    POP SI

    POP CX

    RET

   

    INT7RET:        ;恢复现场

    POP ES

    POP DS

    POP DX

    POP BX

    POP AX

    IRET            ;中断返回

   

    INT7END:

    NOP

INT7 ENDP  

 

CODE ENDS

END START

<think>好的,用户需要查找王爽汇编语言》第四版实验十关于编写子程序的示例代码或教程。首先,我得回忆一下实验十的具体内容。实验十主要涉及子程序的设计,结合call和ret指令的使用。用户可能正在学习如何编写子程序,需要示例代码和步骤指导。根据之前的引用,引用[2]提到call和ret指令用于子程序设计,属于基础内容。引用[3]讨论了宏与子程序的区别,可能相关。需要确认实验十的具体任务,通常是显示字符串、数值转换等子程序编写。 接下来,我应该整理实验十的步骤:安装中断例程、参数传递(寄存器或内存)、保存现场、子程序功能实现、恢复现场。示例代码需要展示如何用寄存器传递参数,比如显示字符串。可能需要使用int10h的BIOS中断,但用户可能更关注子程序结构。注意用户需要的是示例代码,所以应该用汇编语法正确编写,比如使用masm的格式。同时,要提到调试时需要注意数据标号的地址问题,如引用[1]中提到的转移代码时的地址问题,可能涉及数据段正确设置。最后,生成相关问题,帮助用户深入理解子程序参数传递、调试方法、与宏的区别等,参考之前的引用内容。确保回答结构清晰,步骤明确,符合用户需求。</think>### 汇编语言王爽第四版)实验子程序设计指导 实验十的核心目标是掌握**子程序的设计与调用**,重点涉及参数传递、寄存器保护和功能实现。根据书中内容和引用资料,实验十可能包含以下任务: - **编写显示字符串的子程序**(例如在指定位置显示特定颜色字符串) - **数值转换子程序**(如将二进制数转换为十进制ASCII码) - **通过寄存器或内存传递参数**(参考引用[3]中宏与子程序的参数传递差异) --- #### 示例代码框架(显示字符串子程序) ```assembly assume cs:code, ds:data data segment str db 'Hello, Assembly!$' ; 字符串以$结尾 data ends code segment start: mov ax, data mov ds, ax mov si, offset str ; 参数1:字符串地址存入SI mov dh, 8 ; 参数2:行号 mov dl, 3 ; 参数3:列号 mov cl, 2 ; 参数4:颜色属性(02h为绿色) call show_str ; 调用子程序 mov ax, 4c00h int 21h show_str proc push ax ; 保护寄存器 push es push di mov ax, 0b800h ; 显存段地址 mov es, ax ; 计算目标显存偏移地址:行号×160 + 列号×2 mov al, 160 mul dh mov di, ax add di, dx add di, dx ; di = dh*160 + dl*2 show_loop: mov al, [si] cmp al, '$' ; 判断字符串结束符 je show_end mov es:[di], al ; 写入字符 mov es:[di+1], cl ; 写入颜色属性 inc si add di, 2 jmp show_loop show_end: pop di ; 恢复寄存器 pop es pop ax ret show_str endp code ends end start ``` --- #### 关键步骤说明 1. **参数传递**:通过寄存器`SI`(字符串地址)、`DH`(行号)、`DL`(列号)、`CL`(颜色)传递参数[^3]。 2. **显存操作**:显存段地址为`0B800h`,每个字符占2字节(ASCII+属性)。 3. **寄存器保护**:子程序开头通过`push`保护寄存器,结尾通过`pop`恢复[^2]。 4. **结束符判断**:字符串以`$`结尾,避免越界访问。 --- #### 调试要点(参考引用[1]) - **标号地址问题**:若子程序未正确执行,检查`call`指令是否跳转到正确的标号地址。 - **段寄存器设置**:确保`DS`指向数据段,`ES`指向显存段。 - **参数覆盖风险**:子程序中若修改了参数寄存器(如`SI`、`CX`),需提前保存原始值。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值