התגובות שלי בפורום
-
מאתתגובות
-
GalDorמשתתף
The game engine does not support (at the moment) segment prefixes, meaning that
MOV [bx], 0xDEAD
is fine, but
MOV [es:bx], 0xDEAD
throws an unsupported opcode exception.
The way around this is that [bx] references ds by default, so if you edit ds so that it is equal to es, then the code will work, e.g.,
PUSH es ; push the value of es
POP ds ; place it into ds
MOV [bx], 0xDEAD ; write it into [bx], which is [ds:bx] by defaultGalDorמשתתףIn fact, I just checked – and it would appear that you accidently submitted a copy of FSM…
GalDorמשתתףAs far as I can tell, this very different from the survivor you submitted – both of the salvador in the competition attack continuously. In fact, they appear to be very closely related to FSM and its enslaving capability. Are you sure that you did not submit the wrong survivor by mistake?
GalDorמשתתףThe basic thing is this: each team is allocated a segment (usually something like 0x2000) which only they can access. In other words, if XLII1 tries to write to 0x2000:0x0100 he succeeds, if XLII2 tries to read that byte he will also succeed, but if FSM1 tries to do so he will die from memory error.
The value of that shared segment is initially given to your survivors in the ES register. That is, in the example above, the initial value of ES for XLII1 and XLII2 would be 0x2000, but for FSM1 it could be something like 0x2100.
An example for such a thing is the following. In this example, survivor1 saves the address of a part of its code in the shared segment, and survivor2 reads that address and goes there. This way, both survivors are next to each other.
;;;;;;;;;;;;;;;;;;;;;survivor1;;;;;;;;;;;;;;;;;;;;;
@start:
add ax, @code2-@start ;ax now contains the address of @code2
stosw ;this stores ax in the address: ES:DI. DI is initialized to 0, so that address is: ES:0000. Note that we do
;not know the actual value of ES (we don't know if it is 0x2000 or 0x2100) but this does not matter, since
;survivor2 will have the same value in ES.
@code1:
;This will be run by survivor1
;Do stuff here
@code2:
;This will be run by survivor2
;Do stuff here;;;;;;;;;;;;;;;;;;;;;survivor2;;;;;;;;;;;;;;;;;;;;;
push es
pop ds ;DS now points to the shared segment. We don't know in advance what that value is, but we do know
;that survivor1 receives the same value.
lodsw ;This loads the value at DS:SI to ax. But, SI is initialized to 0, so it loads: DS:0000 to ax. Since DS is
;pointing to the private segment, this is the same address where survivor1 stored the address of
;@code2. So, now ax is the address of @code2 (in survivor1's code!).
jmp ax ;This jumps to wherever ax points at. In this case, to @code2.GalDorמשתתףFourth version: has 50% chance to kill alef in exactly 155 cycles, 25% chance to do so in 107 cycles, and 25% chance to do so within 67 cycles.
GalDorמשתתףThird version – has 50% chance to kill alef within 121 cycles, and 50% chance to kill alef within 177 cycles.
GalDorמשתתףOn a side note, you can always hijack one of the six survivors, and then work in parallel with him to kill the rest. (So it only takes about 510 cycles to kill all six survivors)
GalDorמשתתףThe second draft (slightly more optimized) kills alef on exactly 175 cycles…
GalDorמשתתףThe first draft (unoptimized to the extreme) kills alef in 450 cycles on average, and no more than 519…
GalDorמשתתףI do have the intelligent solution – it should be very fast – several hundred cycles. However, I did not participate in the competition today, and have not programmed it yet.
GalDorמשתתףFirst question: the jump opcode, jmp @label actually works by adding a certain amount to ip. Similarly, you can do jmp ax (which sets ip to ax), jmp [bx] (which sets ip to what's stored in [bx]) or jmp far [bx] (which, if I recall correctly, also sets cs to [bx+2]).
Second qeustion: any address in 8086 is always represented by a pair segment:offset, which is than translated into an absolute address by segment*0x10+offset. This has the advantage of allowing you to access 2^20 possible addresses on a 16-bit machine (so you are not limited to 2^16, as you should have been). The current instruction is kept in a similar fashion – your address is cs:ip, where cs is the segment register and ip is the offset within that segment.
Note that a lot of far-call based survivors use the fact that many segments overlap to operate from segments different from the initial arena segment, 0x1000. Instead, they use an offset in an almost completely overlapping segment such as 0x1010 and make sure that they never enp up out of the arena when the actual physical address is calculated. This is used in order to hide their actual address and make finding them musch more difficult for scanners.
GalDorמשתתףShinigami, it appears that we are talking about two different things entirely!
I had in mind a command queue: each thread of each survivor pops an opcode off the queue and pushes its next one and state to the bottom (like in RedCode). This seemed to be a reasonable way to implement "slowing". Twice as many threads means that the queue (and waiting time for each thread) is doubled.
In this implementation, if a thread dies during its turn it simply goes off the queue.
What you thought of means putting it in a "dead state" where it does nothing.
The way I saw it the more threads, the slower each one is, but the less threads, the faster each one is – the queue gets cleared as they are killed.
It appears that we had a misunderstanding.GalDorמשתתףActually, as you kill more and more and are left with only about 80, the speed of reproduction will grow again to exceed your rate of killing them.
You have to "by chance" be able to kill the last few dozens even though they reproduce very rapidly by then.GalDorמשתתףIf others split as well, they still can't write at above 4 bytes per opcode, and for a reasonable replicator, that's a 7/arena chance of dying. The estimation is unchanged. In fact, if the enemy doesn't use call far, the chance of dying is even lower: 5/arena. If the enemy replicates, he still does the same amount of bombardments. Thus having more than one replicator will almost always result in a tie.
GalDorמשתתףDear shinigami, the purpose of my two previous posts (some parts of which are missing) was to show that unless also accompanied by a change of rules, the splitting command is overpowering, and could be used to make invincible survivors. This wouldn't just change the balance – survivors simply wouldn't die in a reasonable amount of time (2^800 rounds is a gross understatement).
-
מאתתגובות