TASM/DOSBox下实现对角线输出CAS?代码解析与实现求助
TASM代码解析与对角线输出修改方案
一、原代码逐段解析
这是一段DOS下的TASM COM程序(org 100h是COM程序的标准标记),以下是各部分功能拆解:
1. 程序头部与数据定义
.model small .code org 100h start: jmp main mess1 db"CAS$" mess2 db"CAS$" mess3 db"CAS$"
.model small:指定小内存模型,适配DOS下的小型程序.code:标记代码段起始org 100h:强制程序加载到内存偏移100h的位置,避开DOS程序段前缀(PSP)的256字节空间start: jmp main:跳过数据区(mess1-mess3)直接执行主逻辑,防止数据被误当作指令执行mess1 db"CAS$":定义以$结尾的字符串,$是DOS中断21h功能09h的输出终止标记
2. 主程序逻辑解析
main proc near ; 清屏初始化 mov ax,03 int 10h
- 调用BIOS中断
int 10h,AH=03是清屏并重置光标的功能,是DOS程序启动时的标准操作
mov ah,05 mov bh,05 mov dh,05 mov dl,05 int 10h
- 调用BIOS中断
int 10h,AH=05是切换显示页的功能,这里设置第5页为当前显示页,同时设置光标到行5列5。但清屏后默认使用页0,这段操作无实际意义,属于冗余代码
mov ah,09 mov cx,03 mov bl,42h int 10h
- 调用BIOS中断
int 10h,AH=09是重复输出字符的功能,但未设置AL寄存器(要输出的字符),会导致输出3个随机垃圾字符。CX=3是重复次数,BL=42h是显示属性:高4位4代表红色背景,低4位2代表绿色前景
mov ah,09 mov dx,offset mess1 int 21h
- 调用DOS中断
int 21h,AH=09是输出以$结尾的字符串的功能,输出mess1的"CAS",位置是之前设置的行5列5
mov ah,02 mov bh,00 mov dh,12 mov dl,40 int 10h
- 调用BIOS中断
int 10h,AH=02是设置光标位置的功能:BH=00指定显示页0,DH=12是行号,DL=40是列号(对应80列屏幕的中间位置)
后续重复的AH=09(BIOS)+AH=09(DOS)操作,都是在同一光标位置(行12列40)输出随机字符和"CAS",导致三个"CAS"完全重叠,这是原代码的核心问题
二、实现右上到左下对角线输出的修改方案
DOS屏幕的坐标规则:行号DH从0(顶部)到24(底部),列号DL从0(左侧)到79(右侧)。右上到左下的对角线要求每个"CAS"的行号递增、列号递减,比如:
- 第一个"CAS":行2,列70(右上区域)
- 第二个"CAS":行8,列55(中间区域)
- 第三个"CAS":行14,列40(左下区域)
修改后的完整代码
.model small .code org 100h start: jmp main mess db "CAS$" ; 无需重复定义相同字符串,复用一个即可 main proc near ; 清屏初始化 mov ax, 0003h int 10h ; 输出第一个CAS:右上位置(行2,列70) mov ah, 02h ; 设置光标位置 mov bh, 00h ; 显示页0 mov dh, 02h ; 行号2 mov dl, 46h ; 列号70(十六进制46h对应十进制70) int 10h mov ah, 09h ; DOS输出字符串 mov dx, offset mess int 21h ; 输出第二个CAS:中间对角线位置(行8,列55) mov ah, 02h mov dh, 08h ; 行号8 mov dl, 37h ; 列号55(十六进制37h对应十进制55) int 10h mov ah, 09h mov dx, offset mess int 21h ; 输出第三个CAS:左下位置(行14,列40) mov ah, 02h mov dh, 0Eh ; 行号14(十六进制0Eh对应十进制14) mov dl, 28h ; 列号40(十六进制28h对应十进制40) int 10h mov ah, 09h mov dx, offset mess int 21h ; 标准退出程序 mov ah, 4Ch int 21h main endp end start
关键修改点说明
- 复用字符串:删除重复的
mess1/mess2/mess3,只保留一个mess,减少冗余 - 移除无效代码:删掉原代码中无意义的显示页切换操作
- 精准控制光标位置:为每个"CAS"设置不同的行号(递增)和列号(递减),实现对角线排列
- 简化输出逻辑:直接使用DOS中断21h的
AH=09输出字符串,避免原代码中输出随机字符的错误操作 - 标准退出方式:用
mov ah,4Ch+int 21h替代int 20h,这是DOS程序的标准退出调用
可选:添加显示属性
如果需要保留原代码的红底绿字属性,可以在清屏操作之后添加以下代码:
; 设置文本属性:红底绿字 mov ah, 0Bh mov bh, 00h mov bl, 02h ; 设置前景色为绿色 int 10h mov bh, 01h mov bl, 04h ; 设置背景色为红色 int 10h
内容的提问来源于stack exchange,提问作者Justin Pimentel
相关产品推荐
相关产品推荐

