title: nasm汇编实现贪吃蛇
date: 2019-12-20 18:43:10


文章目录

  • 0. 前言
  • 1. 需求分析
  • 2. 数据结构设计
  • 3. 程序流程架构
  • 4. 难点分析
  • 5. 具体实现
  • 6. 心得

0. 前言

出于汇编语言课程设计要求,设计一个由nasm汇编语言编写的贪吃蛇程序,可在“裸机”上运行。

详细代码见github。

1. 需求分析

  • 一个正常的贪吃蛇程序
  • 由nasm汇编语言编写
  • 在“裸机”上单独运行,或由自创加载器加载运行

2. 数据结构设计

需要设定的全局变量如下:

  • snake: 蛇身,由N个结点组成(由于纯汇编只有静态数组,所以必须固定蛇身长度的上限进行内存分配)。每个结点4字节,包含的数据如下:

    • 结点位置:

      • 行号,1字节
      • 列号,1字节
    • 方向,1字节
    • 图案,1字节
  • snake_len: 蛇长度,4字节

  • dir: 方向,1字节

  • speed: 蛇前进速度,1字节

  • fruit_pos: 果子位置,2字节:

    • 行号,1字节
    • 列号,1字节
  • score: 分数,4字节

  • xxx_msg: 各类提示信息,字符串形式

  • is_game_over: 游戏是否结束,1字节

全局常量如下:

  • snake_len_max: 蛇身最大长度
  • snake_head_pat: 蛇头图案
  • snake_node_pat: 蛇身结点图案

3. 程序流程架构

在贪吃蛇程序中,应该包含两个“线程”,线程A负责等待用户按键,线程B负责 snake 的前进、检查、更新等操作。

两个线程不受另一方影响,比如线程A在等待用户按键而停滞时,线程B会让 snake 不断前进。

那么问题来了,汇编怎么实现多线程呢?

其实,我们平时遇见的多线程(多进程),本质上是快速交替运行的程序。而在某一个时刻,只有一个程序在CPU运行,但由于快速(毫秒级)交替运行,所以我们看起来像是同时运行的。究其本质,是由操作系统根据一个定时器中断,每过一会儿(毫秒)就帮我们切换运行程序,从而营造出来的假象。(不考虑多CPU)

所以,问题的关键在于定时器中断。首先,它并不是由操作系统提供,而是由硬件产生,所以在没有操作系统的“裸机”上,也能实现多线程/进程。

综上所述,我们只需要将线程B交给定时器中断调用,而线程A由自己运行,那么就可以实现两者同时运行、互不影响。

在下述流程中,Begin即线程A,new_int_1CH即线程B。

Begin:clear() 清屏printStr() 打印提示信息等待用户按键。。。设置 new_int_1CH() 函数为 INT 1CH 中断程序。使得每过一段时间就会执行 new_int_1CH() 函数while 全局变量 is_game_over == 0:等待用户按键。。。根据按键设置全局变量 dirprintStr() 打印游戏结束信息retfnew_int_1CH:snakeMove() 蛇前进snakeShow() 显示蛇snakeCheck() 检查蛇是否撞到自己或者边界if 撞到:还原 INT 1CH 中断程序(在关中断的环境下进行)设置全局变量 is_game_over = 1else:if 吃到果子:蛇尾结点++蛇长度++分数++速度++fruitShow() 显示下一个果子

自顶向下设计,不考虑子函数的实现细节。

4. 难点分析

  • 定时器,定时移动snake
  • 生成随机数

解决方案:

  • INT 8定时器中断,每过55ms就会被触发一次。在INT 8中断程序中,会调用INT 1CH中断,而原本的INT 1CH程序只包含一条返回语句。所以,只需重写INT 1CH中断程序,即可实现定时器功能。

  • 获取随机数:

    mov ax, 0h                 ; 间隔定时器
    out 43h, al                 ; 通过端口43h
    in al, 40h
    in al, 40h
    in al, 40h                  ; 访问3次,保证随机性
    mov bl, 20
    div bl                      ; ax/bl(20) = al......ah
    mov al, ah                  ; 余数
    mov ah, 0
    add al, 1                   ; 1-20的随机数
    

5. 具体实现

代码见github。

由于生成的贪吃蛇二进制程序超过512字节,不能单独做为MBR程序,所以需要由加载器加载,方能运行。

加载器代码见dou-loader。

运行截图如下:

输入7,进入贪吃蛇程序:

Enter键开始:

w,d,s,a键,上右下左移动贪吃蛇。撞到边界或者自身,游戏结束:

6. 心得

项目总结:

  • 贪吃蛇程序的分析——2小时
  • 编写贪吃蛇程序——8小时
  • 代码行数——580

此次项目的完成进度超出预算,其原因如下:

  • 前期基础准备,加载器、时钟中断、键盘中断、IO中断等程序的编写,充分锻炼了汇编代码编写能力。
  • 编码前的项目程序分析十分关键,这使得编码有目的、有依据,而不是凭空想象。其实,这就是软件工程的作用之处,需求分析、概要设计、详细设计、难点解决等。
  • 相对完善、便于理解的注释,一手编码一手注释,很关键。

nasm汇编实现贪吃蛇相关推荐

  1. 贪吃蛇——汇编综合性实验(含实验报告+源码)

    贪吃蛇--汇编综合性实验 完整的实验报告和源码见贪吃蛇--汇编综合性实验(含实验报告+源码) 实现效果 实验原理分析 (1)程序总体设计 贪吃蛇游戏我们并不陌生,简单来说就是一条小蛇通过吃在地图上随机 ...

  2. 8086汇编初学之贪吃蛇

    前言 一直没想过要去学习汇编,觉得需要用汇编的场合无非三种: 1. 与硬件结合很紧密高级语言做不到 2. 时空效率要求甚高算法层面已不能优化到 3. 逆向破解等只能用某些途径看其汇编指令 其余情况下, ...

  3. 基于汇编实现的贪吃蛇游戏

    一 需求分析 现在有的一些人感觉生活都是很无聊的,所以有些时候肯定会玩各种各样的游戏的,有一些大的游戏,玩起来会话掉很多的时间,而且也会花掉大量精力的 ,所以在一些闲暇的时候一些小游戏会博得很多人的喜 ...

  4. 8086汇编贪吃蛇(随机食物+速度递增)

    基于8086实现的贪吃蛇 [cpp] view plaincopy assume cs:code,ds:data data segment dw 200 dup(0)   ;--蛇身坐标 dw 0,0 ...

  5. x8086千行汇编项目——汇编贪吃蛇、画图、两个程序的调度

    特别说明:本博客草稿创建于2018年12月5日(设为私密文章),这已经是作品提交截止日期以后,不过为了进一步避免不必要的麻烦将会在比赛彻底结束后发布为公开文章. 发布日期:2018/12/8 12:0 ...

  6. IA32汇编语言 —— 贪吃蛇游戏

    这里分享一下我的汇编语言课程设计,贪吃蛇游戏 程序使用的资源不超过8086,可以用nasm编译成.com文件,运行在DOSBox环境中 效果演示 文章目录 一.简介 1. 游戏规则 2. 段寄存器安排 ...

  7. 再来一次的C语言贪吃蛇小游戏(一)

    0. 写在开头 学习编程也有两三年时间了,中间也玩(学校安排学习)过很多东西 ,从汇编到C到Java和python.用Java和Python也就图一快,真要体会编程乐趣还得看我C语言(开玩笑 ) 为什 ...

  8. 基于单片机的贪吃蛇游戏

    绪论 1.1 研究背景与意义 随着社会的发展,人们生活的步调日益加快,越来越多的人加入了全球化的世界. 人们不再拘泥于--,J,块天地,加班,出差成了现代人不可避免的公务.而此时一款可以 随时随地娱乐 ...

  9. 【汇编语言】贪吃蛇游戏(一)

      最近刚学完汇编,于是准备做个小游戏练练手.就瞅准了最最最老生常谈的贪吃蛇.   首先贪吃蛇必须是用户让蛇改变方向,蛇就得改变方向,吃到东西蛇会变长.   但我们不太可能一次性就做出来这么多功能. ...

最新文章

  1. webpack 大法好 ---- 基础概念与配置(1)
  2. 使用线程新建WPF窗体(公用进度条窗体)
  3. powerdesigner导出到mysql数据库
  4. jetty启动源码分析
  5. 机器学习算法总结--GBDT
  6. 【Git】Python项目依赖库过大无法提交的问题
  7. DELL戴尔服务器RAID磁盘阵列默认识别更换后的硬盘
  8. OJ:一道考察多态的题目
  9. JavaScript_高程三_01
  10. hikaricp mysql_HikariCP数据库连接池
  11. 易读文库下载器1.2版发布
  12. 清华领军计划计算机试题,清华大学自主招生考试试题难吗
  13. 2014年中国行地产排行
  14. Android之实现遮罩动画的小技巧 类似flash遮罩动画
  15. rpx 和 rem 详解
  16. 基于jQuery实现表单提交验证
  17. 用AnLink多屏协同软件可以同时操作电脑又看手机?
  18. html中两列合并,表格怎么把两列内容合并到一起
  19. 一年中的第几天 哔哩哔哩2020校园招聘笔试题讲解
  20. Python 采集109个中国风风格PPT

热门文章

  1. 团队管理培训总结(2):沟通有法
  2. centos 安装 sun java_CentOS卸载系统自带的OpenJDK并安装Sun的JDK的方法
  3. 第1章 分布式系统概述
  4. ZCMU - 2010: company
  5. JavaScript解除事件绑定处理程序 js事件绑定解除
  6. netdata mysql_Netdata---Linux系统性能实时监控平台部署记录
  7. 网络副业/知识付费实战心得
  8. asp源码和php源码如何使用
  9. VMware ESXi 8.0c - 领先的裸机 Hypervisor (sysin Custom Image)
  10. 二、【React-Router6】一级路由 Routes + Route