【发布时间】:2020-12-17 12:00:43
【问题描述】:
我正在参加保险箱比赛,我得到了这个保险箱:
and al, 0FEh
push ax
clc
mul ax
xor ax, dx
or al, 1
loc_A:
sub ds:0A2h, ax
pop ax
push ax
jnz loc_A
ends
据我了解,为了闯入保险柜,我需要在子操作后得到一个零,以便保险柜停止运行。
所以我想到的解决方案是在 sub 操作后取地址 0A2h 处的值并将其放入 ax 寄存器中,然后我在 ax 寄存器中具有保险库的 ax 的负值,即“ -ax”,那么我只需要做 neg ax,并在地址 0A2h 中将 ax 的值放在 neg 后面。然后 ax-ax = 0。所以这是我构建的代码:
nop
nop
nop
nop
nop
nop
nop
mov ax, [0x00A2]
neg ax
key:
mov [0x00A2], ax
jmp key
代码有效,但只有一半的时间:
safe 和 key 的模拟是在 Core Wars 8086 engine 内完成的。 rules 如下,其中 safe 和 key 都是战争中的幸存者:
幸存者不能在固定地址上加载,因为游戏 引擎每轮将它们加载到一个随机地址。那些节目 生成的必须是 COM 而不是 EXE,并且只包含 8086 指令。
每个幸存者都会收到一组自己的完整寄存器 (寄存器),其他幸存者无法访问。在 此外,每个幸存者都有一个 2048 字节的“个人”堆栈,即 其他幸存者也无法进入。
在运行第一轮游戏之前,游戏引擎 将 arena 中的所有字节初始化为值 0CCh(注意:这 字节值是“不受支持”的指令 - 详情如下)。那么发动机 将每个幸存者加载到竞技场内存中的随机位置,即 - 完全按原样复制幸存者文件的内容。这 两个幸存者之间的距离,以及两个幸存者之间的距离 幸存者和竞技场边缘,保证至少1024 字节。每个幸存者的代码最大为 512 字节。
在第一轮之前,游戏引擎初始化寄存器(的 每个幸存者)到以下值:
- BX、CX、DX、SI、DI、BP - 重置。
- 标志 - 重置。
- AX,IP - 初始幸存者的位置,游戏引擎加载幸存者的竞技场中的随机偏移量。
- CS、DS - 所有幸存者共有的竞技场部分。
- ES - 同一组的幸存者共享内存的段(段)(请参阅高级技术)。
- SS - 幸存者个人堆栈的开始部分。
- SP - 偏移幸存者个人堆栈的开始。
此时游戏以回合开始,每一回合运行游戏引擎运行每个幸存者的下一条指令,直到结束 游戏结束:在 200,000 轮之后,或者当一个幸存者仍然存在时 在竞技场。幸存者在每轮比赛中的顺序 在游戏开始时随机确定,并且不 期间发生变化。
在以下情况下,幸存者将被取消资格:
- 运行非法指令(例如:字节 060h,不翻译成任何汇编指令)。
- 游戏引擎运行“不支持”指令(例如:“INT 021h”)。游戏引擎阻止尝试启动的运行指令 与操作系统或计算机硬件的直接通信。 尝试访问不在竞技场范围内的内存, 并且不在幸存者的“个人”堆栈范围内。
- 攻击其他幸存者是通过在竞技场内存中写入有关他们的代码的信息来完成的(为了让他们执行其中一项 以上三项行动),并因此取消他们的资格。早些时候, 因此,必须找到它们的藏身之处:)
【问题讨论】:
-
您的
key似乎放错了地方。我想你每次都想重新计算。 -
在第二个循环之后,ax 寄存器值没有改变......无论如何,如果我每次都必须计算我是如何得到 50 50 的?
标签: assembly x86 nasm x86-16 corewars