8086汇编初学之贪吃蛇
来源:互联网 发布:集团公司网络规划 编辑:程序博客网 时间:2024/05/16 16:22
前言
一直没想过要去学习汇编,觉得需要用汇编的场合无非三种:
1. 与硬件结合很紧密高级语言做不到
2. 时空效率要求甚高算法层面已不能优化到
3. 逆向破解等只能用某些途径看其汇编指令
其余情况下,用汇编无异于有炮不用偏用鸟枪。
本来准备等自己需求以上场合时再去学,但因为学校举办的汇编比赛,计算机学院都要参加,也算是一个由头,于是开始了我的第一个汇编程序。
运行效果
代码只有400行,功能很简略,实现了最基本的游戏流程,看运行效果
概述
本质上用汇编去写一个贪吃蛇和用其他语言去实现没什么区别,不过是换一种方式表达,当然,是一种更加麻烦的方式。
以前用c++实现过C++贪吃蛇和C++俄罗斯方块。所以对于这类小游戏,该怎么切是知道了,剩下的事就是找家伙了。
要实现这类简易的小游戏,需要二点:
1. 定时器
2. 非阻塞接收按键
有上面两者便可以搞定一切。
但在汇编下,为这两点,耽搁了不少时间。不对,是三点,还有生成随机数(原本很容易的事都变得麻烦了起来)。
定时器
事实上,查了很多资料,但还是不知道怎样去实现定时器,所以这个需求只能变通的解决。
用空循环来控制时间。
非阻塞接受按键
getInput: mov al, 0 mov ah, 1 int 16h;查看键盘缓冲区是否有数据 cmp ah, 1;ah为0表示有,否则没有 je getInputEnd mov al, 0 mov ah, 0 int 16h;从缓冲区读取数据 ;此时值已经在ax里了,做你想做的 getInputEnd: ret
随机数
mov ax, 0h;间隔定时器 out 43h, al;通过端口43h in al, 40h; in al, 40h; in al, 40h;访问3次,保证随机性 ;如果对范围并不需要精确,可以直接与运算来获得, ;否则,用div取余 mov bl, 18 div bl mov al, ah mov ah, 0;此时ax的值就是0~18的
代码
assume cs:code,ds:data,ss:stackdata segment sfood dw 0 sdct dw 0 sbody dw 400 dup(0)data endsstack segment dw 20 dup(0)stack endscode segmentstart: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 20 mov ax, 0b800h mov es, ax mov si, 4 ;保存数据段偏移量 mov cx, 4;初始蛇长度 mov ax, 0A04h s:;初始化蛇 mov ds:[si], ax add si, 2 inc al loop s mov ax, 4d00h;向右 mov ds:[2], ax;初始化方向 call clearBg;清屏 call outBg;输出地图边框 call outBody;输出蛇 call creatFood;输出食物 mov cx, 30 Game: push cx call updateBody mov cx, 0Fh aaaa1: push cx mov cx, 0FFFh bbbb: push cx call getInput pop cx loop bbbb pop cx loop aaaa1 ;jmp GameEnd jmp Game GameEnd: ;退出 ;call outBody mov ax, 4c00h int 21hupdateBody: mov ax, ds:[2] mov di, si sub di, 2 cmp ax, 4800h je shang mov ax, ds:[2] cmp ax, 5000h je xia mov ax, ds:[2] cmp ax, 4b00h je zuo mov ax, ds:[2] cmp ax, 4d00h je you shang: mov ax, ds:[di] sub ah, 1 jmp checkBody xia: mov ax, ds:[di] add ah, 1 jmp checkBody zuo: mov ax, ds:[di] sub al, 1 jmp checkBody you: mov ax, ds:[di] add al, 1 ;mov ds:[di], ax jmp checkBodycheckBody: push ax ;判断蛇头是否碰到地图边界 cmp ah, 0 je GameEnd cmp ah, 20 je GameEnd cmp al, 0 je GameEnd cmp al, 20 je GameEnd ;判断蛇头是否碰到蛇身 mov cx, si sub cx, 6 mov di, 4 s0: mov bx, ds:[di] cmp bx, ax je GameEnd add di, 2 sub cx, 1 loop s0 pop ax ;判断蛇头是否吃到食物 mov bx, ds:[0] cmp ax, bx je addBody jmp updateStartupdateStart: mov cx, si sub cx, 6 mov di, 4 push ax mov dl, ' ';字符 mov dh, 0;颜色 mov bx, ds:[di] call outStr s5: mov dx, ds:[di+2] mov ds:[di], dx add di, 2 sub cx, 1 loop s5 mov dl, ' ';字符 mov dh, 71h;颜色 mov bx, ds:[di] call outStr pop ax mov ds:[di], ax mov dl, ' ';字符 mov dh, 44h;颜色 mov bx, ds:[di] call outStrupdateEnd: retaddBody: mov dl, ' ';字符 mov dh, 71h;颜色 mov bx, ds:[di] call outStr mov ax, ds:[0] mov ds:[si], ax mov dl, ' ';字符 mov dh, 44h;颜色 mov bx, ds:[si] call outStr add si, 2 call creatFood jmp updateEndgetInput:;获取键盘输入 mov al, 0 mov ah, 1 int 16h;接收键盘 cmp ah, 1 je getInputEnd mov al, 0 mov ah, 0 int 16h; mov cx, ax;键盘值在ax ;判断输入 cmp cx, 4800h je gshang cmp cx, 5000h je gxia cmp cx, 4b00h je gzuo cmp cx, 4d00h je gyou jmp getInputEnd gshang: mov ax, ds:[2] cmp ax, 5000h je getInputEnd jmp fx gxia: mov ax, ds:[2] cmp ax, 4800h je getInputEnd jmp fx gzuo: mov ax, ds:[2] cmp ax, 4d00h je getInputEnd jmp fx gyou: mov ax, ds:[2] cmp ax, 4b00h je getInputEnd jmp fx fx:;更改方向标志 mov ds:[2], cx getInputEnd: ret;结束outBody: mov cx, si sub cx, 6 mov di, 4 s1: mov ax, ds:[di] mov dl, ' ';字符 mov dh, 71h;颜色 mov bl, al;列 mov bh, ah;行 call outStr add di, 2 sub cx, 1 loop s1 mov dl, ' ' mov dh, 44h mov ax, ds:[di] mov bl, al mov bh, ah call outStr retoutBg: mov dl, ' ';字符 mov dh, 71h;颜色 mov bl, 0;列 mov bh, 0;行 mov cx, 20 row: push cx push bx call outStr;上边界 pop bx push bx add bh, 20 call outStr;下边界 pop bx inc bl;列加1 pop cx loop row mov bl, 0; mov bh, 0; mov cx, 21 col: push cx push bx call outStr;左边界 pop bx push bx add bl, 20 call outStr;右边界 pop bx inc bh;行加1 pop cx loop col retoutStr: ;在指定位置输出字符 mov al, 80 mul bh;行乘以80 mov bh, 0 add bl, bl; add ax, bx;加上列即为偏移量 push si mov si, ax add si, si mov es:[si], dl mov es:[si+1], dh mov es:[si+2], dl mov es:[si+3], dh pop si retcreatFood:;生成食物 call getFoodPosition mov dl, ' ' mov dh, 071h mov bx, ds:[0] call outStr retgetFoodPosition:;获取食物位置 f1: call getRand mov ds:[0], al call getRand mov ds:[1], al mov cx, si sub cx, 4 mov di, 4 s11: mov ax, ds:[di] cmp ax, ds:[0] je f1 add di, 2 sub cx, 1 loop s11 retgetRand:;获取随机数 范围1~19 mov ax, 0h;间隔定时器 out 43h, al;通过端口43h in al, 40h; in al, 40h; in al, 40h;访问3次,保证随机性 mov bl, 18 div bl mov al, ah mov ah, 0 inc al retclearBg: ;清屏 mov ax, 3h int 10h retcode endsend start
1 0
- 8086汇编初学之贪吃蛇
- 8086汇编 贪吃蛇 源代码
- 8086汇编 贪吃蛇 源代码
- 初学C#:贪吃蛇
- 贪吃蛇汇编代码
- 贪吃蛇汇编
- 初学Unity3D之制作贪吃蛇(一)
- 初学汇编之笔记!
- 贪吃蛇(纯汇编版)
- 8086汇编贪吃蛇(随机食物+速度递增)
- 8086汇编贪吃蛇(随机食物+速度递增)
- 初学汇编之Debug命令
- 贪吃蛇游戏的源代码(汇编)
- MFC之贪吃蛇
- C++ 之 贪吃蛇
- c++之贪吃蛇
- C++之贪吃蛇
- unity3d之贪吃蛇
- bootstrap 图标glyphicons图标符号不正常显示解决办法
- PROJEC LOG 2- VISUALIZATION
- javascript数组和字符串的常见用法
- indexOf()在字符串进行检索
- 特征选择方法之信息增益
- 8086汇编初学之贪吃蛇
- [Leetcode] 3. Longest Substring without Repeating Characters 解题报告
- 特征选择算法之开方检验
- Mysql 对表增加唯一性约束
- QT用md5加密字符串
- [Leetcode] 4. Median of Two Sorted Arrays 解题报告
- 浅谈yield from表达式
- 特征选择方法之互信息
- Android Make sure other views do not use the same id