Assembly x86 Core Wars Safe Challenge(减去核心)

Assembly x86 Core Wars Safe Challenge (Subtract Core)

我正在参加保险箱比赛,我得到了这个保险箱:

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

据我了解,为了闯入保险箱,我需要在子操作后得到一个零,以便保险箱停止 运行。

所以我想到的解决方案是在子操作后取地址0A2h的值并将其放入ax寄存器中,然后我在ax寄存器中输入金库斧头的负值即“-ax”,那么我只需要对 ax 取反,然后将 ax 的值放在地址 0A2h 中。然后 ax-ax = 0。所以这是我构建的代码:

nop
nop
nop
nop
nop
nop
nop
mov ax, [0x00A2]
neg ax
key:
    mov [0x00A2], ax
    jmp key

代码有效,但只有一半的次数:


safekey 的模拟是在 Core Wars 8086 engine. The rules 内部完成的,如下所示,其中 safekey 是 war:

中的幸存者

The survivors cannot place a load on fixed addresses, because the game engine loads them every turn to a random address. The programs that are generated must be COM and not EXEs and contain only 8086 instructions.

Each survivor receives a set of its own complete registers (registers), which is not accessible to the other survivors. In addition, each survivor has a "personal" stack of 2048 bytes, which is also inaccessible to the other survivors.

Before running the first round of the game, the game engine initializes all the bytes in the arena to the value 0CCh (note: this byte value is an "unsupported" instruction - details below). The engine then loads each survivor to a random location in the arena memory, ie - copies the contents of the survivor file exactly as it is. The distance between two survivors, as well as the distance between the survivor and the edge of the arena, is guaranteed to be at least 1024 bytes. The code for each survivor has a maximum of 512 bytes.

Before the first round, the game engine initializes the registers (of each survivor) to the following values:

  • BX, CX, DX, SI, DI, BP - Reset.
  • Flags - Reset.
  • AX, IP - The position of the initial survivor, the random offset in the arena to which the survivor is loaded by the game engine.
  • CS, DS - The segment of the arena common to all survivors.
  • ES - A segment (segment) for the memory shared by survivors of the same group (see Advanced Techniques ).
  • SS - Beginning section of the personal stack of the survivor.
  • SP - Offset The start of the personal stack of the survivor.

At this point the game begins in rounds, with each round running the game engine running the next instruction of each survivor, until the end of the game: after 200,000 rounds, or when a single survivor remains in the arena. The order in which the survivors will play in each round is determined at the beginning of the game at random, and does not change during it.

A survivor is disqualified in the following cases:

  • Running an illegal instruction (example: byte 060h that does not translate into any assembly instruction).
  • Running an "unsupported" instruction by the game engine (example: "INT 021h"). The game engine prevents running instructions that try to initiate direct communication with the operating system or computer hardware. Attempt to access memory that is not within the realm of the arena, and not within the realm of the "personal" stack of the survivor.
  • Attacking other survivors is done by writing information about their code in the arena memory (in order to get them to perform one of the above three actions), and consequently to disqualify them. Earlier, therefore, one has to find where they are hiding :)
l: 
   mov bx, 0a2h 
   mov dx, 0xffff            
   mov word [bx], dx
   nop
   nop
   mov ax, word [bx]
   sub dx, ax 
   mov word [bx], dx 
   mov dx, 0xffff 
   jmp l  

试一试。

我认为您的方向是正确的。您已经注意到,在保险箱进入循环之前的所有计算都可以忽略(它们是转移注意力的信息)。需要理解的重要一点是,safe 中的循环完成一次后,所有后续循环将始终减去相同的值。您需要做的是确保我们 忽略第一个值 安全写入 [0A2h],然后一旦我们知道它已被写入,一旦我们将 [0A2h] 清零,然后等待它第二次写入 [0A2h] 然后我们只是否定内存中的那个值。一旦取反 safe 将退出循环,因为 safe 中减法的结果将为 0,循环条件将退出。 NASM 应该工作的代码是:

start:
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    ; At this point the safe is guaranteed to have written to [0A2h] exactly once
    ; Zero out the value at [0A2h]
    mov word [0A2h], 0
    nop
    nop
    nop
    ; At this point the safe is guaranteed to have written to [0A2h] exactly twice
    ; Negate the value at [0A2h] so that safe will exit (SUB will result in value 0)
    neg word [0a2h]

    ; End in an infinite loop
    jmp $

MASM(6.x+)/TASM/JWASM 版本为:

.model tiny
.code

start:
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    ; At this point the safe is guaranteed to have written to [0A2h] exactly once
    ; Zero out the value at [0A2h]
    mov word ptr [ds:0A2h], 0
    nop
    nop
    nop
    ; At this point the safe is guaranteed to have written to [0A2h] exactly twice
    ; Negate the value at [0A2h] so that safe will exit (SUB will result in value 0)
    neg word ptr [ds:0a2h]

    ; End in an infinite loop
    jmp $

end