首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

組合語言經典:一個有趣的 DOS 打字遊戲原始碼解析

     編輯:組合語言

前言

這是一個使用 MASM 5.0 編寫的純 DOS 環境打字練習遊戲,展示了早期 PC 時代程式設計師如何直接操作硬體(螢幕、鍵盤、計時器)實現互動式遊戲。程式碼結構清晰,大量使用巨集簡化重複操作,是學習 16 位元實模式組合語言、BIOS 中斷(INT 10h, INT 16h, INT 21h)與遊戲迴圈邏輯的優秀教材。

遊戲功能與操作

  • 選單系統:提供 6 種速度等級(極慢至最快),支援鍵盤選擇與 ESC 退出。
  • 遊戲畫面:頂部顯示隨機字母序列,字母逐行向下掉落。
  • 核心玩法:玩家必須在字母觸底前輸入對應鍵盤字元「擊落」字母,得分與否決定遊戲續行。
  • 即時控制:SPACE 暫停/繼續,ESC 返回主選單。
  • 失敗處理:字母觸底顯示「Game Over」,可選擇重玩或退出。

關鍵技術點解析

1. 影片模式與螢幕操作 (INT 10h)

使用 AH=00h 設定 80x25 文字模式,AH=06h 捲動/清除視窗,AH=02h 設定游標位置,AH=09h/0Ah 顯示字元/屬性。遊戲邊框由 Init_game 巨集繪製。

2. 鍵盤輸入與非阻塞檢測 (INT 16h / INT 21h)

AH=00h 等待按鍵(選單用),AH=01h 檢查鍵盤緩衝區(遊戲主迴圈用),配合 INT 21h AH=06h, DL=0FFh 實現非阻塞輪詢,確保遊戲流暢運行。

3. 字母生成與下落邏輯

預置三組 78 字元字母表(letters),配合 position_flag 與 life_flag 陣列追蹤每個字母的水平位置、垂直行數與存活狀態。主迴圈中根據速度參數延遲,逐行更新字母位置並重繪。

4. 碰撞檢測與分數機制

玩家輸入字元經 ADD AL, 23h 簡易混淆後與當前掉落字母比對,命中則清除該字母並生成新字母(字母碼 +7 循環),未命中觸底則判定失敗。

完整原始碼(節選關鍵段落)

;--------------------------------------------------------------------------------
;此模板是純DOS程序代碼,需要MASM5.0,編譯時請使用"編譯 -> DOS"方式。
;--------------------------------------------------------------------------------
Init_game macro op1,op2,op3,op4,op5,op6
 mov cx,00h
mov dh,op1
mov dl,op2
op6:
mov ah,02h
mov bh,00h
int 10h
 push cx
mov ah,0ah
mov al,op3
mov bh,00h
mov cx,01h
int 10h
pop cx
 inc cx
inc op4
cmp cx,op5
jne op6
 endm
...
data segment
 linjiang db "Made by lin jiang$"
no db "NO.:021411$"
meg db "Let us have a game!!Come on!!$"
meg1 db "**Select Menu**$"
...
letters db "jwmilzoeucgpravskntxhdyqfb"
db "iytpkwnxlsvxrmofzhgaebudjq"
db "nwimzoexrphysfqtvdcgljukda"
 letters_bak db "jwmilzoeucgpravskntxhdyqfb"
db "iytpkwnxlsvxrmofzhgaebudjq"
db "nwimzoexrphysfqtvdcgljukda"
 letter_counter db 0
life_flag db 78 dup(0)
 position_flag db 78 dup(0)
present_position db 1
 data ends
...
code segment
main proc far
 assume cs:code,ds:data,ss:stack
start:
 mov ax,data
 mov ds,ax
 ...
 clear_screen 00d,00d,24d,79d
 Init_game 00d,00d,0ah,dl,80d,nextsign1
 ...
 menu 01d,15d,meg ;菜單信息的宏展開
 ...
 input: mov ah,02h
 mov bh,00h
 mov dh,22d
 mov dl,33d
 int 10h
 mov ah,01h
 int 21h
retry: cmp al,"1"
je speed1
...
 begin:
 clear_screen 01d,01d,23d,78d
 ...
 nextletter: ; 初始化屏幕上方的字母
 mov ah,02h
 mov dl,[si]
 int 21h
 ...
 from_front: ; 相關循環的算法
 sub present_position,78d
 jmp gobackto_si
 ...
 print:
 mov ah,0ah
 mov al," "
 mov bh,00h
 mov cx,01h
 int 10h
 inc dh
 mov ah,02h
 mov bh,00h
 int 10h
 mov ah,0ah
 mov al,[di]
 mov bh,00h
 mov cx,01h
 int 10h
 ...
 disappear: ; 擊中字母後的相關處理
 pop cx
 pop cx
 mov ah,0ah
 mov al," "
 mov bh,00h
 mov cx,01h
 int 10h
 jmp hit
 ...
 fail: mov ah,0ah ;遊戲失敗後的相關處理
 mov al," "
 mov cx,01h
 int 10h
 ...
 over: clear_screen 01,01,23,78
 mov ah,02h
 mov bh,00h
 mov dh,11d
 mov dl,15h
 int 10h
 mov ah,09h
 lea dx,failmeg3
 int 21h
 ...
 mov ax,4c00h
 int 21h
main endp
code ends
end start

歷史價值與啟示

這段程式碼不僅是懷舊展示,更體現了資源極度受限(無作業系統保護、無圖形庫、記憶體 640KB)下,程式設計師對硬體的深度理解與極致優化。巨集的大量使用減少重複代碼,狀態機設計清晰分離選單、遊戲、暫停、失敗等狀態,非阻塞輸入輪詢保證即時性——這些思想在現代遊戲開發中依然閃耀著智慧的光芒。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved