1 Star 0 Fork 10

asassasa11 / asm_for_all

forked from 吴烜 / asm_for_all 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

本共享库采用GPLV3许可证,请在所有提交代码开头包括许可证,如下:

;   This program is free software: you can redistribute it and/or modify
;   it under the terms of the GNU General Public License as published by
;   the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.
;
;   This program is distributed in the hope that it will be useful,
;   but WITHOUT ANY WARRANTY; without even the implied warranty of
;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;   GNU General Public License for more details.
;
;   You should have received a copy of the GNU General Public License
;   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  • 目标:共享一些常用代码块,以及示例代码。代码请遵循规范。为方便索引生成,请在开头注释中说明开发环境和最佳编译运行环境、版本;程序整体用途,输入输出,备注等。范例:TIME_DELAY.asm

  • 库结构:分成example(示例),与template(代码块)。分别再按照指令集(x86,arm...)与系统(console,win32,linux...)分两层,如下:

  • example
    -- x86
    --- console
    --- win32
    --- linux(暂无)
    -- arm(暂无)

  • template
    -- x86
    --- console
    --- ...

管理员责任:对不同用户共享的代码进行走查(code review),根据代码规范对开发者(包括其他管理员)进行修改建议。

根据代码开头的注释,生成代码索引如下。工具代码请见项目管理工具/IndexGenerator.

[ 4chess.asm](http://git.oschina.net/zhishi/asm_for_all/blob/master/example/x86/console/ 4chess.asm)
程序名称:4chess.asm
功能:四子棋(棋盘游戏)
环境:16BIT DOS实模式(windows/dos或dosbox)最好全屏
编译器:MASM 5.1-6X (这个是com格式,masm5.x须用EXE2BIN 4CHESS.EXE 4CHESS.COM,Masm6.x须加入:ml /AT参数
用法:看说明
返回值:没有
破坏寄存器:不适用
简易版四子棋简介:
四子棋是一款普遍流行的简易型桌面游戏,据说,虎克船长曾因专注于此游戏而长期隐身在住所,当船员们发现船长的这一专长之后,他们称这个游戏为“船长的情妇”。
四子棋是个双人游戏,两人轮流下棋,棋盘由行和列组成的网格,每个选手每次下一个子直到两人中有一人的棋子连成一条水平线、垂直线或者是对角线。
本实验需要在LC-3中实现简易版四子棋的游戏,两位选手通过键盘和输出窗口轮流交互操作,棋盘由6X 6的网格组成。
游戏规则如下:
两位选手依次轮流落子;
选手没有悔棋;
有子的地方不能继续落子;
直到有一方的四个棋子能够连成一条水平线、垂直线或者是对角线;
如果棋盘已满,无人获胜,则平局。
解题:
游戏是6x6棋盘,连四可以有横,直和斜。
一行中,六中连四,即是三种方式,6列X3即18
同理,直行也是18
斜也是18
换言之,全部胜利条利是18*3=54种。
这样少的条件,直接制作一个表,只要是表内的就是胜利
6X6共36BIT
四字是DQ (64BBIT),即54个DQ的阵列就是胜利条件表
样子大约是
win_table label byte
dq 111100000000000000000000000000000000b
这是横列的1个资料
注意:这只是一个范例程式,具备最起码的功能,没有太花巧的技术,也没有人机对战,
若你需要其他功能或加入或删减任何代码,请随便,但不能要求作者为你订制特定的功能或
根据功课要求而改变这个子程序改变那个子程序,若是代码错误或优化代码的意见,
则欢迎提出:)
因为没多少空闲,程序只加了一些简单解释。
Connect Four Chess

2014cal.asm
程序名称:2014cal.asm
功能:1980-2099年历
环境:16BIT DOS实模式(windows/dos或dosbox)
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:不适用
原题目:http://tieba.baidu.com/p/3817224129
实验设计:年历(2014)
原题目只要求制作2014年历,但这不具通用性,现在这个是1980-2099的年历,
每一次显示半年,按左右键查询其他年份,按ESC閃人。
其实吧里已有TajuraTong姑娘曾写了一个,功能十分完整。
http://tieba.baidu.com/p/3680768090
只要稍稍修改就可以显示半年历了,我已征得TajuraTong姑娘的同意修改她的
程式,在这里发布她的心得和释出她的代码/和本人小部份修改,
这个程式包括想法和技术细节,都是她原创,本人纯粹是一只copycat。
----------TajuraTong的理论----------------
程式在纯dos下或者window 的 dosbox也可(最好用全萤幕) 。
R,L 和 <- -> 均可左右查看月份,年份范围由(1980-2099),这是int 21h的限制。按ESC可离开。
int 21h里ah=2ah是读取日期,ah=2bh是设定日期,代码中没有建立每年/每月的资料结构,查看月份时才即时读取。
想法:
读日期时,windows用日期函数,dos的可以用int21h,2ah 或者系统中断int 1Ah
看看int21h好了,int 21h里ah=2ah是读取日期,ah=2bh是设定日期
先看看2A是做什么的:
INT 21 - DOS 1+ - GET SYSTEM DATE
AH = 2Ah
Return: CX = year (1980-2099)
DH = month
DL = day
---DOS 1.10+---
AL = day of week (00h=Sunday)
其中AL很重要,等于当天日期的星期数!我们只要把日期先 [设定]是某月的第1日,
然后再读取该日的日期,那么就知道该月的第1日是星期一、二还是什么!
接下来再看看ah=2Bh
INT 21 - DOS 1+ - SET SYSTEM DATE
AH = 2Bh
CX = year (1980-2099)
DH = month (1-12)
DL = day (1-31)
Return: AL = status
00h successful
FFh invalid date, system date unchanged
注意这个AL = 状态,若是0表示成功,ff表示失败!
我们知道,一年的月份中,最少是28日,最多是31日,只要由28日(dl=28)开始设定该月日期,
成功则日期就dl +1,即29,再回去试,若再成功再dh+1回去试,试到32日,回存失败(al=ff)
那最后的dl减1,就是该月的天数,这样就不用理会什么月大月小,二月有28或29日的麻烦问题了。
到此,我们已经解决了两个关键问题,该月第一天的星期数,该月是28-31那一项?
好了,设想完毕,开始设计表格!
先排日期,我们把它排到惯见的方式:
db ' 1 2 3 4 5 6 7 '
db ' 8 9 10 11 12 13 14 '
db '15 16 17 18 19 20 21 '
db '22 23 24 25 26 27 28 '
db '29 30 31 '
每一个日期占3byte,[空白][word],word=2byte即日期,由1-31
月份:
db 'January ','February ','March ','April '
db 'May ','June ','July ','August '
db 'September ','October ','Novermber ','December '
占14bytes,每个月份等长,不足的补以空白,这样,用指标x14,就是月份的字串位置了
指标可以用左右键去加或减。
再建立一个日历的字串缓冲,形式如下:
年份 / 月份    <-可变
S M T W T F S  <-不变
  1 2 3 4 5 6 7
8 9 10 11 12 13 14  < -1到6列可变
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
方法:
0.先把原来日期存起来,int21, ah=2ah,得到年/月/日,存起来当作[年指标]和[月指标]的初始值
1.利用设定和读取得出,算出该月的第一天星期数和该月的天数,把该年由hex转成文字存到缓冲字串的起点
2.月份,利用月份指标x14得出该月字串存到缓冲区
3.送星期字串, S M T W T F S 到缓冲区
4.利用该月第1天的星期数x3,跳过日期第一列的空白,星期数多少就跳多少,得出的位置就是第1日的目的位置
5.利用该月天数x3,得出要搬动多少byte到上面[4]得出的位置28天就搬28x3,31天就搬31x3,来源是 day_str
6.搬完后,日历字串缓冲完成,开始由印缓冲字串
7.利用int21 ah=2,或者int 10 ah=13h列印8列文字,每印完一列,游标移下一列。
8.利用int 16h, ah=0读取使用者输入,RL <- ->
9,加减年份变数 或 加减月份变数,判定正确后回到代码 s10地址,重新清空缓冲字串
根据年份变数和月份变数调数搬移的资料和位置,回到方法:1
10.若输入ESC则离开,回存已经预先读好的原来日期。
----------TajuraTong的理论(完)----------------
注意:这只是一个范例程式。
若你需要其他功能或加入或删减任何代码,请随便,但不能要求作者为你订制特定的功能或
根据功课要求而改变这个子程序改变那个子程序,若是代码错误或优化代码的意见,
则欢迎提出:)
因为没多少空闲,程序只加了一些简单解释,若不明白看一下TajuraTong的理论就是。

2014easy.asm
程序名称:2014easy.asm
功能:2014年历简化版
环境:16BIT DOS实模式(windows/dos或dosbox)
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:不适用
原题163楼
http://tieba.baidu.com/p/3740277941?pn=5
这个简化版以之前的2014cal.asm做蓝本
利用2014/1/1是星期三,和
month_days db 31,28,31,30,31,30,31,31,30,31,30,31
这两个资料计算其余的月份,不用int21函数,
背景和其他复杂的技术,
只加了计算月份的count_month_day而已

2014fool.asm
程序名称:2014fool.asm
功能:2014年历陽春版
环境:16BIT DOS实模式(windows/dos或dosbox)
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:不适用
原题163楼/166楼
http://tieba.baidu.com/p/3740277941?pn=5
要求:如果还没学BIOS中断,不用int 10h这些,仅用DOS的int 21h中断该怎么写啊?
这个[陽春版]以之前的2014easy.asm做蓝本
应要求,不用int10h,只用3个int21h/ah=7读键,ah=09印字,ah=4ch离开

ASCII2BCD.asm
下行定义你的CPU MODEL

Dir_a_file.asm
这是一个印出档案资料最最基本的程式,它先建立一个DTA
再呼叫int21h / ah=4eh找出档案的资料,然后依次印出
档名,档案大小,最後修改日期和最後修改时间
若给出档名有万用字元如* 和?,再用int21h / ah=4fh ,第二个找到的
档案可再在DTA抓出资料,如此类推,这相当于部份dir的功能

Directory_list.asm
上一个程式dir_a_file.asm是印出指定档案的资料,这个增加一些功能,
首先读入参数,例如键入的参数是 A*.,程式就以A.作为搜寻的目标,
若没有输入参数,则以
.*(万用字元)作为搜寻的目标。
同样利用int21h / Ah=4Eh做第一次搜寻,印出,再利用int21h / Ah=4Fh
做后续搜寻,直到传回cf=1为止,表示当前文件夹再也找不到档案了,
最后印出全部显示档案和文件夹的总数。
程式执行时,可按ESC离开,按空白键暂停。
这程式实现了DOS的DIR部份功能,没有实现的是多层文件夹和排序等等,
留待有空再说了。

DispRegM.inc
DispRegM.inc
这是testreg.asm子程序,请看testreg.asm说明
副程序名称:dispregM.inc
功能:配合regsub.inc的宏
环境:16BIT DOS实模式
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:没有

DOS文本写显存.asm
下行定义你的CPU MODEL

HEX2ASCII.asm

HEX2BCD.asm
下行定义你的CPU MODEL

HEXVIEW.asm

Little_clock.asm
程序名称:clock.asm
功能:常驻计时器/闹钟
环境:16BIT DOS实模式
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:不适用
这是吧上某人的功课吧
这题目有普遍性,涉及的问题较多,所以独立发一帖,希望多些人看到.
参照 “定时响铃”的例子及其它MASM程序的例子,实现 INT 1C
MYINT1C 实现的功能在屏幕的右上角显示秒表或时钟,按ESC,
退出程序。
说明:
1.实现基本的秒表功能,即参照8.5范例给出的响铃程序改写,
实现简单的计时和暂停、中止等功能;
2.时钟复杂一些,按照书后BIOS/DOS中断附表实现从系
统取时间,并能够对其进行设置和相应的计时功能。
解题
DOS的常驻,时钟比较简单,基本上拦截1CH,抓取系统时间,
找个地方显示一下就完事了,至于计时,方法也有许多,1CH
本身就是每1/18.2秒运行一次,所以同时也有计时功能.
常驻的方法用DOS的21H,AH=31H或者INT27也可以.
这个小小CLOCK程式的计时和读时间不用任何中断int21h,ah=2ch
或int 1Ah,而是直接读取40:6C - 40:6D的系统累加时间,这相容度好像
还大,测试在windows/dos 和dosbox都能正常运行
编译:因为程式是com,masm 5.x 须要exe2bin 转成com> exe2bin clock.exe clock.com
masm 6.x的话加 ml /AT 的设定可直接转成com
用法:
clock ;在右上角显示时间
clock u ; 移除常驻
clock s mm:ss
mm是分钟,ss是秒
键入clock s 3:10  
右上角显示倒数计时3:10 ..3:09...3:08 直到00:00时显示3秒红色 -alarm-文字
然后回到正常系统时间
若键入 clock s 10,程式会视为倒数10分钟,若只要倒数秒
可键入 clock s 0:10 ;则数10秒
若clock已经常驻,也可以键入clock s mm:ss 去设定新的倒数
代码有简单的英文注解(要交功课的同学请自行添加/翻译注解)

NameTelREC.asm
程序名称:NameTelREC.asm
功能:人名/电话简单记录表
环境:16BIT DOS实模式(windows/dos或dosbox)
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:不适用
这是贴吧上一个问题,什么也没有,只有一幅加重肩颈炎病情的图。
http://tieba.baidu.com/p/3829872119
题目要求建立一个只有9个人名/电话资料的资料纪录,包括输入和查询功能,列出全部/刪除记录是我手痒加的。
题目有普通性,代码示范了查询和表列的技术,并不复杂。
加了簡單的解釋,若不明白,debug一下就是。
注意:这只是一个范例程式,具备最起码的功能,没有太花巧的技术。
若你需要其他功能或加入或删减任何代码,请随便,但不能要求作者为你订制特定的功能或
根据功课要求而改变这个子程序改变那个子程序,若是代码错误或优化代码的意见,
则欢迎提出:)

RDCMOS.asm
下行定义你的CPU MODEL
head 磁头
track 磁道
sector 扇区
Sector of per Track 每磁道扇区数

regsub.inc
副程序名称:regsub.inc
功能:印出所有寄存器
环境:16BIT DOS实模式
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:没有
regsub.inc
这是testreg.asm子程序,请看testreg.asm说明

SQRT_calculate.asm
程序名稱:計算平方根
功能:輸入一個帶小數的數,計算平方根並輸出
環境:16BIT DOS實模式
編譯器:MASM 5.1-6X
用法:輸入一數(可帶小數),按ENTER

TestReg.asm
程序名称:Testreg.asm
功能:利用子程序印出所有寄存器(范例程式)
环境:16BIT DOS实模式
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:没有
--------- register_display (Sub program)------------
原发问人希望改为子程序。
于是有了这个,可以说是之前X86_Register_display.asm的进阶版。
改写完了,我发觉这个小玩意也有一点用途。
它可以实时显示所有寄存器,子程序运行之后,因不改变寄存器值,
这就相当于一个软中断,放在程式的某些需要监视变数、观看loop值,
或者查看呼叫中断后传回的值.....等等场合,都能适用。
为了简便使用,我分别写了两个inc档,Regsub.inc 和DispRegM.inc
Regsub.inc是子程序,DispRegM.inc是一个宏
另外写了一个测试用Testreg.asm,就是现在这个。
使用方法:
(1)纳入inc档,在档顶加入一句:include dispregm.inc
 因为宏中会使用push 立即数的代码,所以档顶至少要加入.286或以上(如.386)
(2)纳入inc档,在档尾加入一句:include regsub.inc
(3)可在程序中任何位置加入宏,如
  @DisplayReg 10,01  ; 立即值,在第10行,印出01(蓝色)的全部寄存器值
 or @DisplayReg AX,BX ;寄存器赋值,用AX和BX指定的行和颜色
 or @DisplayReg variable1,variable2 ;变数赋值,用变数指定的行和颜色
要注意的是,若要插入@DisplayReg 的程式是驻留式的
即是使用int21h/ah-31h 或int 27h那种常驻程式,则
include regsub.inc [必须]放在驻留部份的最底

驻留代码
.驻留的底部...include regsub.inc

初始化代码
end

这是一般驻留程式的结构,被载入后会做一些初始化动作,
然后[只]把驻留代码留在内存,初始化代码则[丢弃]!
所以插入的include regsub.inc [必须][必须]
放在驻留部份的最底,否则.....
还有regsub.inc代码里会自行设定.286的伪代码
若初始化代码有用到.386,请自行再加上
就算最顶有.386,也会被regsub.inc的.286取代
若不是驻留程式,则include regsub.inc最好放底

.include regsub.inc
CODES ENDS
END START
--Code Start----------------------------------------------------------------

TIME_DELAY.asm
副程序名稱:delay_proc
功能:時間延遲
環境:16BIT DOS實模式
編譯器:MASM 5.1-6X
用法:把延遲秒數放入AX,呼叫delay_proc
返回值:沒有
破壞寄存器:沒有
備註:若AX=0,即時返回

X86_Register_display.asm
--------- register_display ------------
Q. 98楼
http://tieba.baidu.com/p/3740277941?pn=3
问题:
现在一个现实问题,大部分初学者,不知道各寄存器的值!
希望写一个打印各寄存器值的程序!不要中断,不要32位汇编!
就像C语言里面的printf函数!
回答:
列印寄存器的值和列印一般资料没什么分别
和列印16bit/32bit的hex值一样.........
其实进入debug ,按R,就是16bit寄存器的值
这个代码正是仿debug [R]的作法,印出各寄存器和Flag的值
但这个不是真正的debug,没有单步,所以CS:IP和flag等,知道了也没什么意义.
倒是可以看看程式被载入时各寄存器的初始值

Y-ABCDE.ASM
程序名称:Y-ABCDE.ASM
功能:根据公式,计算Y值
环境:16BIT DOS实模式(windows/dos或dosbox)
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:不适用
应sjydhqhome的遨请,为这烂题目写了一个汇编,正想贴出却发现原贴被删了,好样的!
没有原题目,大概就是读取五个数ABCDE,根据公式:
(Y=AxB+C/D-E),把正负结果分别存入BUF1和BUF2...
草草写的这一个,少于300行..
为了加点趣味和亲和性,所以加了运算元的显示,若不要这些,大概150行就可以了
程式只读入两个数字,接受负数,输入到D值时,若发现为0,不会接受并清除
输入时,程式会显示和指出运算过程,光是这些烂功能就花掉百多行代码..
结果直接印在后面,这样直观一些..
按ESC或ENTER离开
时间有限,加了小量解释,没空侦错,若有bug请报告..

http://pan.baidu.com/s/1kT7rtiB

三数排序.asm
设有3个单字节无符号数存放在BUF开始的缓冲区中,编写一个能将它们从大到小从新排列的程序。

字数据数组排序.asm
设某一数组的长度为N个元素,均为字数据,试编制一个程序使该数组中的数据按照从小到大的次序排列。(要从大到小排序,只需把JBE改为JAE即可)

正负数判断.asm
判断一个数X的正,负数,还是零。(假设是正数,输出+,是负数,输出-,是零,输出This is a zore !)

范围0-16求最小数.asm
求十个数中的最小数,并以十进制输出。(若要求最大的,只要把JC 改为JNC 即可)(仅局限于0---16间的数比较,因为ADD AL,30H只是针对一位的十六进制转换十进制的算法)

駐留時鐘(註解).asm
程序名称:clock.asm
功能:常驻计时器/闹钟
环境:16BIT DOS实模式
编译器:MASM 5.1-6X
用法:看说明
返回值:没有
破坏寄存器:不适用
这是吧上某人的功课吧
这题目有普遍性,涉及的问题较多,所以独立发一帖,希望多些人看到.
参照 “定时响铃”的例子及其它MASM程序的例子,实现 INT 1C
MYINT1C 实现的功能在屏幕的右上角显示秒表或时钟,按ESC,
退出程序。
说明:
1.实现基本的秒表功能,即参照8.5范例给出的响铃程序改写,
实现简单的计时和暂停、中止等功能;
2.时钟复杂一些,按照书后BIOS/DOS中断附表实现从系
统取时间,并能够对其进行设置和相应的计时功能。
解题
DOS的常驻,时钟比较简单,基本上拦截1CH,抓取系统时间,
找个地方显示一下就完事了,至于计时,方法也有许多,1CH
本身就是每1/18.2秒运行一次,所以同时也有计时功能.
常驻的方法用DOS的21H,AH=31H或者INT27也可以.
这个小小CLOCK程式的计时和读时间不用任何中断int21h,ah=2ch
或int 1Ah,而是直接读取40:6C - 40:6D的系统累加时间,这相容度好像
还大,测试在windows/dos 和dosbox都能正常运行
编译:因为程式是com,masm 5.x 须要exe2bin 转成com> exe2bin clock.exe clock.com
masm 6.x的话加 ml /AT 的设定可直接转成com
用法:
clock ;在右上角显示时间
clock u ; 移除常驻
clock s mm:ss
mm是分钟,ss是秒
键入clock s 3:10  
右上角显示倒数计时3:10 ..3:09...3:08 直到00:00时显示3秒红色 -alarm-文字
然后回到正常系统时间
若键入 clock s 10,程式会视为倒数10分钟,若只要倒数秒
可键入 clock s 0:10 ;则数10秒
若clock已经常驻,也可以键入clock s mm:ss 去设定新的倒数
這個和之前的little_clock是一樣的,只是加了中文解釋,為免影響編譯,所以另開一個
若有編譯錯誤,請下載little_clock.

HEX2ASCII.asm
MASMPlus 代码模板 - 控制台程序

TextOutput.asm

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/ourasm/asm_for_all.git
git@gitee.com:ourasm/asm_for_all.git
ourasm
asm_for_all
asm_for_all
master

搜索帮助