无INT 10H指令的Intel 8086汇编数字金字塔程序开发求助
8086汇编数字金字塔(无INT 10H)代码问题排查与修正
问题描述
需要实现数字金字塔显示(每行数字从当前起始值递增,数字个数逐行加2,整体居中),要求不使用INT 10H指令,直接操作VGA文本显存(0B800h段)。现有代码运行结果不符合预期,需排查问题并修正。
现有代码问题分析
- 字符类型错误:代码中
mov al, 65加载的是大写字母'A'的ASCII码,而需求是显示数字,应使用数字的ASCII码(如'1'对应49)。 - 显存地址计算逻辑混乱:
原代码通过shl bx,1、add bx, dx等操作计算显存地址,完全不符合VGA文本模式的地址规则(每行80字符,每个字符占2字节,行偏移=行号×160,列偏移=列号×2),且循环中会破坏bx的原始值,导致后续字符位置计算错误。 - 循环控制变量不合理:
dh从1开始计数行号,而VGA文本模式行号通常从0开始(共25行);di作为行数控制变量,与dh的逻辑关联混乱。 - 颜色属性不一致:在
wiersz循环中每次重新赋值ah, bl,但bl在循环中被修改,导致同一行内字符颜色不同。
修正后的代码
Progr segment assume cs:Progr, ds:dane, ss:stosik start: mov ax, dane mov ds, ax mov ax, stosik mov ss, ax mov ax, offset szczyt mov sp, ax ; 清屏:VGA文本显存段0B800h,共25行×80列=2000个字符,每个字符占2字节 mov ax, 0B800h mov es, ax xor di, di mov cx, 2000 xor ax, ax ; 字符0+黑底黑字属性 rep stosw ; 初始化变量 mov dh, 0 ; 当前行号(0~24) mov dl, 39 ; 当前行起始列号(80列居中,奇数个字符起始位置) mov al, '1' ; 起始数字ASCII码 mov cx, 1 ; 当前行显示的数字个数 mov ah, 07h ; 字符属性:黑底白字(可修改为0Fh白底黑字等) mov si, 25 ; 金字塔总行数 piramida: push cx ; 保存当前行数字个数 push dx ; 保存当前行起始列号 ; 计算当前行显存起始偏移:行号×160 + 列号×2 mov bx, dh shl bx, 6 ; bx = dh×64 shl bx, 1 ; bx = dh×128 mov ax, dh shl ax, 5 ; ax = dh×32 add bx, ax ; bx = dh×160(行偏移) mov ax, dl shl ax, 1 ; ax = dl×2(列偏移) add bx, ax ; bx = 最终显存偏移地址 wiersz: mov es:[bx], ax ; 写入字符与属性 add bx, 2 ; 移动到下一个字符位置 inc al ; 数字递增 dec cx jnz wiersz pop dx pop cx inc dh ; 切换到下一行 dec dl ; 起始列左移,保持居中 add cx, 2 ; 下一行数字个数加2 dec si jnz piramida ; 程序退出 mov ah, 4Ch mov al, 0 int 21h Progr ends dane segment dane ends stosik segment dw 100h dup(0) szczyt Label word stosik ends end start
代码说明
- 显存地址计算:严格遵循VGA文本模式规则,行偏移为
行号×160(每行80字符×2字节),列偏移为列号×2,两者相加得到准确的显存偏移地址。 - 字符与属性:固定
ah为显示属性,确保同一行字符颜色一致;al从'1'开始,逐字符递增实现数字序列。 - 循环控制:每行起始列逐行左移1位,数字个数逐行加2,完美实现居中的金字塔形态,总行数适配25行标准文本模式。
内容的提问来源于stack exchange,提问作者user17872526
相关产品推荐
相关产品推荐

