You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 17:46:29