471字节俄罗斯方块汇编程序源代码及详细注释

更新时间:2023-07-23 06:20:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

汇编源代码

;2006年新年公开我写的471字节俄罗斯方块汇编程序源代码及详细注释!
;471 bytes GAME! By Dwing
;Only for DOS/Win9x/WinME/DosBox(注意不能直接在Win2000以上系统运行)
.model tiny
.386
.code
$shape equ 008h
$backg equ 0dbh
$up   equ 72
$left  equ 75
$right equ 77
$down  equ 80
org 100h
start: int 10h         ;设置显示模式0(40*25*16色字符模式)
push 0b800h       ;字符缓冲区段=b800h
pop ds         ;ds=b800h
push ds
pop es         ;es=b800h
xchg ax,di       ;di=0000h
mov ax,0700h+$backg   ;开始画边框,ax=字符(0dbh)及属性(灰色)
mov cx,ax        ;cx=数量
rep stosw        ;覆盖全屏
mov ax,0e30h      ;开始画数码框,ax=字符('0')及属性(黄色)
mov cl,6        ;cl=数字个数(6)
mov di,2*(40*23+17)   ;di=数字显示屏幕偏移位置
rep stosw        ;显示数码
xor ax,ax        ;开始画中间空框,ax=空字符
mov di,2*(40*2+15)   ;di=空框第一行屏幕偏移位置
@nextbl:mov cl,10        ;cl=每行块数(10)
rep stosw        ;画一行空格
add di,2*(15+15)    ;计算下一行屏幕偏移位置
cmp di,2*(40*22+15)   ;判断是否画完最后一行(共20行)
jb short @nextbl    ;没画完则循环
@rernd: in al,40h       ;开始随机选择方块类型,al=时间随机值
and al,0111b      ;al只取0-7
jz short @rernd    ;如果是0则重新选择(只选1-7,共7种)
dec ax         ;1-7变为0-6
mov bx,2*(40*2+15+4)  ;方块起始屏幕偏移位置
jnz short @t      ;如果不是0(长条形方块需特殊处理)则跳转
mov bx,2*(40+15+4)   ;长条形方块的起始屏幕偏移位置上移一行
@t:   xchg ax,bp       ;bp=方块起始屏幕偏移位置
call @isok       ;判断新产生的方块能否放置
jz short @goon     ;能放置则跳转
@end:  call @dispb       ;不能放置情况:先显示方块
push cs
pop ds         ;ds=当前程序段
lea dx,msg1       ;dx="GAMEOVER"信息地址
mov ah,9        ;ah=9(显示字符串)
int 21h         ;显示"GAMEOVER"
@esc:  in al,60h       ;读键盘
dec al         ;"ESC"扫描码=1
jnz short @esc     ;如果没有按"ESC"则跳回继续读键盘
mov ax,3        ;ax
=DOS默认显示模式(3)
int 10h         ;设置显示模式3(80*25*16色字符模式)
retn          ;退出
@goon: mov cl,0ffh       ;新方块能放置情况:先进入延时状态
cmp cl,40h       ;cl=

汇编源代码

循环等待次数
jae short @wait     ;确认cl不小于40
mov cl,40h
@wait: call @dispb       ;显示当前新方块
push cx         ;进入等待状态
xor cx,cx        ;cx=等待时间(微秒)低字
mov dx,1000       ;dx=等待时间(微秒)高字
mov ah,86h
int 15h         ;等待
pop cx         ;退出等待状态
@t4:  mov ah,1
int 16h         ;判断键盘缓冲区是否有字符
jz short @loop     ;没有按键则跳出键盘处理部分
xor ax,ax
call @disp       ;清除新方块的显示
int 16h         ;读取键盘缓冲区字符=>ah
mov al,ah        ;al=ah
cmp al,$up       ;判断是否是上方向键
jnz short @k1      ;不是则跳转
push bp         ;保存当前新方块的摆放形状
movzx bp,cs:[bp+bkv]  ;改变新方块的摆放形状
call @isok       ;判断是否能放置
jz short @loop_    ;能放置则跳出键盘处理部分
pop bp         ;不能放置则恢复新方块原来形状
loop @wait       ;继续下一次等待
@k1:  push bx         ;保存当前新方块的位置
cmp al,$left      ;判断是否是左方向键
jnz short @k2      ;不是则跳转
dec bx         ;新方块左移一个位置(2个字节)
dec bx
@test: call @isok       ;判断是否能放置
jz short @loop_    ;能放置则跳出键盘处理部分
pop bx         ;不能放置则恢复新方块原来位置
loop @wait       ;继续下一次等待
@k2:  cmp al,$right      ;判断是否是右方向键
jnz short @k3      ;不是则跳转
inc bx         ;新方块右移一个位置(2个字节)
inc bx
jmp short @test     ;剩下的处理同"左方向键"
@k3:  pop bx         ;恢复新方块原来位置
cmp al,1        ;判断是否是ESC键
jz short @end     ;如果是则跳转到退出程序段
jmp short @ok      ;如果是其他按键则跳出延时状态
@loop_: pop ax         ;清除保存的新方块位置
@loop: loop @wait       ;继续下一次等待
@ok:  push ax         ;保存按键扫描码
xor ax,ax        ;延时过后进入方块下落部分
call @disp       ;清除新方块的显示
add b
x,2*40       ;新方块下移一个位置(2个字节)
call @isok       ;判断是否能放置
pop ax         ;恢复按键扫描码
jnz short @down     ;如果不能放置新方块则跳转
cmp al,$down      ;判断是

汇编源代码

否是下方向键
jz short @ok      ;如果是则继续下落
jmp short @goon     ;不是则进入下一次延时
@down: sub bx,2*40       ;恢复新方块原来位置
call @dispb       ;显示新方块
xor ax,ax        ;进入判断是否有一行已满
mov dx,ax        ;ax=dx=0
mov si,2*(40*2+15)   ;si=中间空框的起始屏幕偏移位置
@nextl: mov di,si        ;di=当前判断的屏幕偏移位置
mov cl,11        ;判断10次(10+1)
repnz scasw       ;扫描一行
jz short @skip     ;如果有空位则跳出
pusha          ;进入消除一行部分
mov si,di
sub si,2*40       ;si=上一行屏幕偏移位置
mov cx,si        ;cx=移动字符个数
std
rep movsb        ;移下一行
cld
mov di,2*(40*2+15)   ;di=中间空框最上一行的屏幕偏移位置
mov cl,10        ;一行10个方块
rep stosw        ;清除最上一行
popa          ;退出消除一行部分
inc dx         ;分数基值+1
add dh,dl        ;累计当前分数
@skip: add si,2*40       ;下一行偏移位置
cmp si,2*(40*22)    ;判断是否判断完所有行
jb short @nextl    ;没有则继续下一行判断
and dx,dx        ;判断是否有得到当前的分数
jz short @t_      ;没有则跳过
@t00:  mov di,2*(40*23+21)   ;数码位屏幕偏移位置(第2位)
@t0:  mov byte ptr[di],30h  ;置0
dec di         ;进一位(倒退2个字节长度)
dec di
cmp di,2*(40*23+20)   ;判断是否进入第3位
jnz short @t000     ;如果不是则跳过
dec byte ptr cs:[@goon+1];每100分等待次数减1(加速)
@t000: inc byte ptr[di]    ;当前数码位+1
cmp byte ptr[di],3ah  ;判断数码位是否超过9
jz short @t0      ;如果是则跳转(进位)
dec dh         ;当前分数累计值-1
jnz short @t00     ;如果分数没加完则继续累加
@t_:  jmp @rernd       ;继续产生下一个新方块
@isok: mov si,bp        ;判断是否能放置方块子模块
shl si,2        ;si=方块形状标号*4(占4个字节)
xor ax,ax
mov dx,ax        ;ax=dx=0
add si,offset bks    ;si=方块形状位置描述指针
push cx         ;保存cx
mov cl,4        ;cl=方块数(4)
@nextb: db 2eh         ;lod
sb cs: (al<=cs:[si])
lodsb          ;载入方块位置描述(位置偏移)
mov di,ax
or dx,[di+bx]     ;判断小方块是否冲突
loop @nextb       ;继续判断下一个位置描述
pop cx   

汇编源代码

    ;恢复cx
retn          ;返回
@dispb: mov al,$shape      ;显示方块子模块,al=方块形状标号
mov ah,cs:[bp+bkc]   ;ah=方块颜色值
@disp: mov si,bp
shl si,2        ;si=方块形状标号*4(占4个字节)
push cx         ;保存cx
mov cl,4        ;cl=方块数(4)
@nextb_:movzx di,cs:[si+bks]  ;取方块描述
mov [di+bx],ax     ;显示一个小方块
inc si         ;si=下一个位置描述
loop @nextb_      ;继续画下一个小方块
pop cx         ;恢复cx
retn          ;返回
bkc   db 2          ;方块颜色值
db 9,12,13,14, 11,10
db 9,9,9,   12,13
db 11,11,11,  10,10,10
db 2
bkv   db 18         ;方块形状链表
db 7,10,11,4, 12,15
db 8,9,1,   2,3
db 13,14,5,  16,17,6
db 0          ;下面是方块形状描述
bks   db 40*2,41*2,42*2,43*2 ; ****         0
db 1*2,40*2,41*2,42*2 ;  *   **  **  ** 基本形状*7
db 1*2, 2*2,40*2,41*2 ; ***  **   **  ** 1-4
db 0*2, 1*2,41*2,42*2 ;
db 0*2, 1*2,40*2,41*2 ;
db 0*2,40*2,41*2,42*2 ;  *    *
db 2*2,40*2,41*2,42*2 ;  ***  ***     5-6
db 1*2,40*2,41*2,81*2 ;  *     *     扩展形状*12
db 40*2,41*2,42*2,81*2 ; **  ***  **
db 1*2,41*2,42*2,81*2 ;  * * * * *     7-9
db 0*2,40*2,41*2,81*2 ;   **  **
db 1*2,40*2,41*2,80*2 ;   *  *      10-11
db 1*2,41*2,80*2,81*2 ;  *    **
db 40*2,41*2,42*2,82*2 ;  *  *** *
db 1*2, 2*2,41*2,81*2 ;  **   * *     12-14
db 0*2, 1*2,41*2,81*2 ;* **    *
db 40*2,41*2,42*2,80*2 ;
*  *  *** *
db 1*2,41*2,81*2,82*2 ;*  *  *  **    15-17
db 2*2,42*2,82*2,122*2 ;*           18
msg1  db 9,9,'GAMEOVER',9,9,'$'
end start

本文来源:https://www.bwwdw.com/article/4h0m.html

Top