楚门 发表于 2012-5-12 19:01:15

这里有玩磁芯大战的么?

本帖最后由 楚门 于 2012-5-15 06:18 编辑

今天无意中看到有关磁芯大战的一篇博客,一下子就来了兴趣,就赶紧下了一个mars模拟器,试验了几个在网上下载的几个程序,实在太有趣了(看这两个程序争夺计算机资源),准备在业余的时候研究一下这个游戏,现在我仅仅知道这种程序要用汇编来写,有其自己的汇编语法,但不知道怎么编译(网上的资料很少),所以在这里发个帖,有兴趣的朋友一起在这交流交流,附件中有windows下的mars模拟器,花费了好些力气才找到,就不收鱼币了**** Hidden Message ********* Hidden Message *****
**** Hidden Message *****
唉,,看了一晚上,还是很多细节没整明白,真的很纠结,资料太少,翻译的又不是那么简明,弄个IDE,大家慢慢摸索吧

先把附件里面的一些资料贴出来让大家有个了解,大家觉得感兴趣就下载吧
< 一 > 简介
程序大战也叫磁核大战,英文名为"CoreWars",是一个很古老的游戏,当年比尔.盖茨上学时就有这个东东了,不过国内玩的人很少。 目前一些免费Unix如FreeBSD等的ports里就有他。
这个游戏可以从名字也能看出来就是程序之间的大赛。就是大家都写一个程序,然后我们把这些程序都放到内存,然后开始"并发"运行,看最终的结果是谁的程序消灭了内存中的其他程序而存活了下来。
这一程序对抗模型可以看作是原始的病毒对抗。每个程序都要尽力的消灭其他程序,为了能够生存,程序应该能保护自己,不断移动自身来躲过其他程序的攻击或当自身受到攻击后能自我修复。
当然这些程序不是运行在家用PC上,也不是随便使用大家常用的intel汇编来编写。其运行平台为Mars机。Mars是一种简单的计算机,他有固定的8000个内存单元,和约10来个指令。然后整个大战程序就是由这些指令完成。
< 二 > Mars体系结构
Mars机器由一个组内存单元,一个CU单元,一个简单进程管理系统,和一组指令集构成。
Mars机的标准主要参考pMars虚拟机器标准,主要有两个:88标准和94标准。以下都是默认为88标准,扩展94标准会专门标识出来。
该系统内存大小固定为8000个内存单元,每一个内存单元由5个部分构成:
<1> OPCODE区:操作数区,该区域指定了机器指令,如MOV ,ADD。
<2> A数据区 :一个32位的数据存储区,存放相应数据,如128,-100。
<3> A数据区寻址修饰:指定了A数据区的寻址方式。
<4> B数据区。
<5> B数据区寻址修饰。
( 94标准中加入了一个新的部分 <6>操作数修饰区。)
系统的寻址方式分为立即寻址,直接寻址,间接寻址。
( 94标准中加入了新的间接A减1寻址、间接A加1寻址、间接B减1寻址、间接B加1寻址)
系统寻址都是相对当前IP为基准寻址的,这是Mars系统和传统计算机最大的不同之处。如 mov 0,1表示将当前指令所在的内存单元拷贝一份到当前指令所在内存单元的下一个内存单元。
CU单元用于执行相应的指令,配合CU单元还有一个隐含的寄存器IP,每次执行单元执行IP指定的内存单元的指令。
简单进程管理器管理进程。系统的进程由一个先进先出队列构成。每次管理系统将当前进程的执行地址出队列放入IP寄存器,然后CU单元执行指令,最后将该进程的下一条指令地址放入队尾。如果该进程产生新进程,则在队尾再加入新进程的起始执行地址。简单进程管理器保证每个进程轮流执行,当一个进程执行了DAT或者执行了0被除的操作则该进程结束。
系统指令包含:
   DATMOV ADDSUBJMPJMZJMNCMPSLTDJNSPL
( 94标准中加入了新的指令: SUB MUL DIV MOD SEQ SNE NOP LDP STP )
Mars机目前你所见到的几乎都是软件模拟系统,模拟器模拟Mars系统工作。有的模拟器支持88标准,有的支持94标准,有的支持88标准并部分支持94标准,所以你在选择一个模拟器时应该好好看看它支持那个标准。
Mars机的汇编程序通常称为RedCode,而Mars模拟器几乎都集成了一个RedCode的编译器,将RedCode程序编译为机器码写入内存。
系统初始时内存中都是DATA $ 0,$ 0 ,每一个程序加载到内存的随机位置,当多个程序都加载完后系统给每个程序创建一个进程,此时每个进程在进程队列中的位置是随机的,然后系统开始运行。然后各个程序开始进行对抗,看最终谁能生存下来。
<三> RedCode简单语法(按94标准)
指令写法可以记做<label> OPCODE < OP_modify > <A_modify> A_field ,<B_modify> B_field
                                             ------------------   ------------------
                                                   整体记做A          整体记做B
<>包含的部分可以省略。
通常A表示源地址,B表示目标地址。
OPCODE包含:
   DAT   中止进程
   MOV   移动数据A到B
   ADD   A加B并将结果存入B
   SUB   A减B并将结果存入B
   MUL   A乘B并将结果存入B
   DIV   B/A并将结果存入B,如果A=0进程结束
   MOD   B%A并将结果存入B,如果A=0进程结束
   JMP   跳转到A
   JMZ   如果B=0则跳转到A
   JMN   如果B!=0则跳转到A
   DJN   先将B减1, 如果B!=0跳转到A
   SPL   开启一个新进程,新进程起始执行地址为A
   SLT   如果A<B跳过下一条指令
   CMP   和SEQ相同
   SEQ   如果A=B跳过下一条指令
   SNE   如果A!=B跳过下一条指令
   NOP   空指令,什么也不干。
   LDP STP    本地地址操作指令,一般都没有实现,这里就不解释了。
   DAT指令可以只有A区域出现,此时一般编译器会将内存的A区域拷贝一份到B区域。
   JMPSPL指令也可以只有一个A区域出现,此时一般编译器会将内存的B区域作为
$ 0
OP_modify包含:
   .A   指令读写目的地址的A区域
   .B   指令读写目的地址的B区域 (如果Op_modify没有指定,则默认使用该规则)
   .AB指令读A指定地址的A区域,结果写入B指定地址的B区域
   .BA指令读A指定地址的B区域,结果写入B指定地址的A区域
   .F   指令读A指定地址的A和B区域,操作结果写入B指定地址的A和B区域
   .X   指令读取A指定地址的B区域,操作结果写入B指定地址的A区域;
      然后读取A指定地址的A区域,进行同样的操作操作结果写入B指定地址的B区域
   .I   指令读写源和目标地址的整个内存单元。
      (mov指令没有指定OP_modify,并且源操作数不是立即数时使用该规则)
Modify指定了寻址方式:
    #   立即数
    $   B直接寻址
    @   间接寻址
    <   B先减1,再间接寻址
    >   B先减1,再间接寻址
    *   A间接寻址
    {   A先减1,再间接寻址
    }   A先加1,再间接寻址
值得注意的是地址跳转相关的指令A区域不能为立即数,加减乘除模指令的B区域不能为立即数,否则要么模拟器报语法错误,要么作为执行非法指令中止进程或者作为空指令处理。Filed就是指定数据的地方了。

程序注释符为";",从;到行尾均作为注释。但有几个特殊的注释,作为程序信息:
;name   filename指定程序的名字
;author author    指定程序的作者
;debug 指定是否调试程序,但不是每个模拟器都实现
此外不同的模拟器也有自己特定的特殊符号。宏一般不同的模拟器都有自己的一套,但通常都实现了EQU语法:
label EQU 表达式         (表达式可以为数字或标号的加减乘除)
ORG 数字或标号       指定程序执行的开始地址
END <数字或标号>   程序结束,此后的部分不会被编译,如果指定了一个数字或标号则作为程序开始地址。
< 四 > 语法实例讲解
以上介绍了整个语法体系,看了后你应该已经云里来雾里去了,我们在这里以实例讲解RedCode。
以下我们写一个完整的RedCode文件:

;name Test
;author cloud

org 1
datadat 5
   mov data , @ data
   mov -2   , < data
   mov # 3, data
   jmp -1
end编译器编译后将各指令的各个区域写入对应内存单元的对应区域。假如程序放到内存的0001单元到0005单元写入内存后反汇编过来就是:
0001DAT $ 5 , $ 5
0002mov $ -1, @ -1
0003mov $ -2, < -2
0004mov # 3 , $ -3
0005jmp $ -1, > 2程序入口地址org 1,就是程序的第1条指令开始(编号从0开始),就是地址0002
0002处mov指令的寻址如下:
源地址: $-1 ,就是直接寻址,以当前地址(0002)相对的-1处的地址作为源地址 ,即 0001
目的地址: @ -1 ,就是间接寻址,以当前地址(0002)相对的-1处的地址的B区域作为直接寻址地址 就是0001处的B数据区的数据5作为直接寻址地址,取出0001处的5作为直接寻址,5也是一个相对地址,相对于0002就是地址0007,最终目标地址为0007那么最终就是将0001的内存单元拷贝一份到0007,0003处的mov源地址一样,操作的是0001的地址,目标地址为: < -2 ,就是取出相对0003地址-2的地址(就是0001)的B数据区(就是5),先将其减1(即为4),然后在存放回去(0001处的B数据区变成4),将得到的结果(4)作为直接寻址,目标地址就是相对当前地址(0003)为4的地址,即0007
最终结果和上一条指令一样,但真正内存单元拷贝时001的B数据区已经变成了4,0004处的结果就是把3放到0001的B数据区中,0005处的结果就是把0007的B数据区的数据加1,然后跳转到0006.
< 五 > 简单实例
作为对抗程序最重要的就是生存,一个最简单的程序就是
jmp 0始终跳转到自身,死循环,自己没有攻击能力,唯一取胜的方法就是期望对手自己死亡,可谓守株待兔。但这个程序一个问题是自己在内存中的地址固定,很容易收到攻击。
下面这个程序可以说是非常出名的IMP程序了:
mov 0,1它不断把自己移动到下一个内存单元,然后执行到下一个内存单元执行。这个程序具有一定的攻击能力,能够覆盖别人的程序,但是覆盖他人程序后也不能取胜,因为不能导致他人程序执行中止进程操作,唯一的取胜方法也是等待他人程序死亡,但自身在内存中的位置不断移动,生存能力比jmp 0强。对付IMP程序的方法也很简单:
jmp 0 , < -2这段代码始终跳转到自身,但是跳转前会将前面的第2个内存单元的B数据区数据减1,当imp程序将自己移动到该地址后将被修改为mov 0,0 这样下次IMP执行时执行mov 0,0没能将自己移动,但执行地址已经到达下一个内存单元,而Mars系统初始化时内存单元为 dat 0,0 这就导致IMP程序执行一个DAT指令而导致进程中止。攻击他人程序通常都是通过扔出一个DAT来覆盖他人程序,使得其他程序因执行DAT而中止,比如下面这个程序:
org start
      dat 0,5
start    mov -1,@-1
      jmp -1,> -2
end第一次mov -1 , @ -1 将 dat 0, 5 拷贝一个到相对为5的地址处进行一次轰炸, jmp -1 ,> -2 将 dat 0 ,5 修改为 dat 0,6。然后跳转执行mov -1, @ -1 ,执行mov时导致将dat 0,6 拷贝到相对为6的地址进行轰炸如此循环,最终将对整个内存以dat轰炸一遍,可谓杀伤力非常。像这样的轰炸程序是非常有效的攻击,现在的很多程序都是靠这种手法攻击他人,然后利用IMP的方法移动自己避免被攻击。
当然,你也可以每隔几个单元轰炸一次:
org 1
   dat 0,5
   mov -1,@-1
   add #4 , -2
   jmp -2
end这个程序每次将dat 0,5的B数据区加4,然后在MOV处以此寻址进行轰炸,所有长度大于4的程序都容易受到它的攻击。作为对抗手段,程序可以采用哨兵概念,先在代码前面放一个数据,然后检查该数据是否被改变,如果被改变表示其他程序运行到了该处,或者攻击了该地址,自己就可以采取相应的对策,把自己移动躲避攻击或者发动对该地址的攻击。程序对抗非常复杂,你可以到网上多看看别人的程序,这里就不多讲了。
<六>如何实战
看到这里是不是心里痒痒想实战一下,写个redcode代码开始作战?没问题,偶早就给大家准备好了一个Mars虚拟机,你得到的是一个.zip压缩包,解开后目录结构如下:
ProgBattle.exe   执行程序。
         说明.txt
         程序大战.txt
         redcode目录         里边有一些教学用的代码如何使用?非常简单:运行ProgBattle.exe然后打开你编写的(或网上找到的)redcode程序文件,最后点击“运行”按钮,这些程序便开始在虚拟机内部开始大战了。比如你打开redcode\目录下的imp_gate.red和imp.red然后运行就可以看到我们上一节讲到的imp攻防实例了。redcode目录下的.red文件都是非常好的作战程序范例,随便找个文件编辑器打开即可,你也可以参考编写自己的攻击代码。
ProgBattle.exe程序实现了Mars虚拟机88标准和部分94标准,网上找到的很多程序都可以在里边直接运行,另外该程序还实现了:
反汇编 : Dis按钮;
单   步: 按下“下箭头”按钮,然后点运行按钮;
追   踪: 按下“文本”按钮,这样就可以看到程序运行情况,同时该功能可以减慢程序运行速度,让你更清楚的看到作战过程。
暂   停 :按下“暂停”按钮。使用前看看程序目录下的 说明.txt文件




ArcherJhon 发表于 2012-5-12 19:30:57

在 黑客传说 的小说里貌似看到过。。

楚门 发表于 2012-5-12 19:41:48

ArcherJhon 发表于 2012-5-12 19:30 static/image/common/back.gif
在 黑客传说 的小说里貌似看到过。。

嗯这本小说我也看过

苹果之家 发表于 2012-5-12 19:54:36

看看隐藏的是什么?

楚门 发表于 2012-5-12 20:02:06

我也对这个游戏完全不了解,但会继续找一些资料分享

冰海蓝 发表于 2012-5-12 20:28:13

还有这种游戏么。。

chulinux 发表于 2012-5-12 20:29:01

看看隐藏的是什么?

Kinich_Ahau 发表于 2012-5-12 20:36:12

有,就是不知道怎么用!!

xjm 发表于 2012-5-12 20:38:09

呵 好有趣的东西啊

楚门 发表于 2012-5-12 20:59:19

Kinich_Ahau 发表于 2012-5-12 20:36 static/image/common/back.gif
有,就是不知道怎么用!!

呵呵我也不知道慢慢摸索

楚门 发表于 2012-5-12 21:00:00

xjm 发表于 2012-5-12 20:38 static/image/common/back.gif
呵 好有趣的东西啊

嘿嘿   是啊

楚门 发表于 2012-5-12 21:00:52

冰海蓝 发表于 2012-5-12 20:28 static/image/common/back.gif
还有这种游戏么。。

《黑客传说》这本小说提到过这个游戏

唯舆之缌 发表于 2012-5-12 21:18:55

百度过   不过好像语法不一样

楚门 发表于 2012-5-12 21:26:07

唯舆之缌 发表于 2012-5-12 21:18 static/image/common/back.gif
百度过   不过好像语法不一样

嗯   指令也很少

冰封绝恋 发表于 2012-5-12 22:00:30

围观........

冰封绝恋 发表于 2012-5-12 22:09:26

楼主,你能说说怎样玩的吗?我下载到了,但不会玩。

楚门 发表于 2012-5-12 22:17:05

冰封绝恋 发表于 2012-5-12 22:09 static/image/common/back.gif
楼主,你能说说怎样玩的吗?我下载到了,但不会玩。

我也正在研究,我直接从网上下载了两个程序,然后运行wincode.exe,点setup——>ADD然后把你下载的以red为扩展名的代码文件加载进去,然后点击start就可以看到两个程序争夺模拟器内存的结果,目前我正在研究这种类似于汇编语言的语法和mars模拟器的结构

冰封绝恋 发表于 2012-5-12 22:24:41

楚门 发表于 2012-5-12 22:17 static/image/common/back.gif
我也正在研究,我直接从网上下载了两个程序,然后运行wincode.exe,点setup——>ADD然后把你下载的以red为 ...

你的wincode.exe在哪下载的,不是直接点CoreWin就行了吗,还要下载别的东西的?

楚门 发表于 2012-5-12 22:41:44

冰封绝恋 发表于 2012-5-12 22:24 static/image/common/back.gif
你的wincode.exe在哪下载的,不是直接点CoreWin就行了吗,还要下载别的东西的?

额    我说错了   就是corewin.exe   汗。。。。。不好意思啊

优质矿泉水 发表于 2012-5-12 23:03:40

貌似在小说里看到过喔。。
页: [1] 2 3 4
查看完整版本: 这里有玩磁芯大战的么?