I figured maybe it's time for a discussion about scanning. The best 7 programs on the hill right now (this is my OPINION) are: Smooth Noodle Map, Crimp 2, Charon v6.0a, Agony 2.4, Sucker 4, Note Paper, and izotrop (but Imps! is still my favourite)… 4 of these are CMP scanners that are probably VERY similar.

B-field scanning: Let's tackle this first. B-field scanning is neat because it's pretty fast (faster than bombing) and can be used in a pretty small loop. Here is an example:

loop    add #STEP, target
target  jmz loop, START

        mov BOMB, @target
        jmp loop

If you follow this through, you can see that we are scanning at the rate of 1 location per two cycles, which is better than a standard bombing loop (1/3). Also the bomb can be much more powerful (we can do multiple MOVs whenever we drop out of the main loop) because this only happens when a location with a non-zero B-field is found. Every extra MOV that a bomber would do would cost him in the loop speed.

The main problem with B-field scanning is that JMZ will not see instructions that have a zero in the B-field. Minimizing the instructions that contain non-zero B-fields is an excellent defensive method in any warrior.

The other problem is that inherent to all scanners. When fighting a scanner, a bomber is dropping targets that the scanner will go and investigate (and thus waste time). This, the above, and the fact that CMP scanners are so much faster is why there are no good B-field scanners on KotH. Even XTC seems a pretty pathetic challenger.

CMP scanning: this is a much cooler and elegant way to scan the core. By properly using the CMP instruction we can scan 2 locations in 3 cycles. The basic thing to keep in mind is that CMP a,b will fail if a is a DAT and b is not or vice versa.

There are basically three types of CMP scanners:

  1. A CMP scanner that compares a constant location to a changing one. This is the most straight forward way to use the CMP. We do a CMP, skip if CMP succeeds ADD #STEP to the target pointer, JMP back. This amounts in a 1/3 location/cycle ratio and is obviously not worth it:

    target  cmp -1, START
            jmp gotone
    search  add #STEP, target
            jmp target
    
    gotone  mov BOMB, @target
            jmp search
    
  2. A small distance CMP scanner (a prefect example is Stefan Strack's Agony). If we know the fixed distance between a and b in CMP a,b we can bomb location a thru b and therefore assume we hit something that was at a and/or at b. Remember, when a CMP a,b fails (finds something) we do not know whether it was at a or at b. The trick is how to increment both a and b and keep the distance between them constant:

    target  cmp START, START+DIST
            jmp gotem
            add inc, target
            jmp target
    
    gotem   [bomb in between target's b field and (b field - DIST)]
    
    inc     dat #STEP, #STEP
    

    By adding inc to target we are incrementing the a and b fields of target by a constant amount. If you chose the DIST to be small, each <bomb> (in Agony's case a SPL 0 blanket between x and y) will not slow you down too much.

  3. An a and b field bombing CMP scanner. The first of these was Andy Pierce's Comper (a very primitive example, but the first that I know of). The idea is that if we scan with a CMP a,b, we don't know which location was the actual hit. So... we just bomb both of them to make sure:

    target  cmp START+DIST, START
            jmp gotem
            add inc, target
            jmp target
    
    gotem   [bomb target's b-field]
            add switch, target
            jmp target
    
    inc     dat #STEP, #STEP
    switch  dat #DIST, #DIST
    

    There are two ways to set the DIST constant up so that this type of scanner can work. One is the axis method. In a core size of 8000, we can add 4000 to both the a and b fields of target and effectively switch them. Work this out if you don't believe it. The only problem with this type of scanning is that programs can hide completely from this method. If a program mirrors itself to 4000 away, this type of scanner will not see it (remember, CMP a,b fails only if what's at a and what's at b are not equal).

    The other way is one I recently put into Charon v6.0a sending into the top five for the last week. This is also the method that Andy uses in Crimp 2. The problem is, how do we bomb the a. We can subtract the DIST between the a field and the b field from the b field, thus making b point to where a pointed to before. But what do we do with a? There is a very simple and efficient way to solve this. If we have a search STEP, and a DIST=(coresize-(abs(STEP-coresize)/2) (where abs is a function that returns an absolute value result) we can do the same thing as the previous example and still have similar results. We gain immunity from mirror protection and a miniscule amount of speed. Lets analyze. The distance between a and b is DIST. When we add switch to target, b will point to where a pointed to. But what does a point to? If the target was at b, we bomb b and add switch (b become a and a moves on). The CMP at target succeeds when we jump back to it and we continue scanning. If, however, the target was at a, we bomb b and add switch. Now the b field of target is pointing to where a pointed to and therefore CMP fails. We bomb b (which used to be a) and add switch again. If you notice, we have bombed the original a and b locations, and are ready to pick up scanning as if all we did was add inc.

    It's complicated, I know, and I'm terrible at explaining these things. Just check out the formula and do it on paper and you should see why this works. And if you don't believe, check out the KotH standings and see where Crimp 2 and Charon v6.0a are.

    [Crimp, by the way, is Charon (not Agony, I do not know why anyone ever thought so) with B-field damage. The bomb used by both these warriors is SPL 0, JMP -1. This is very damaging and quick to drop.]

Finally, what is the downside to a CMP scanner. Blind bombers leave a thousand targets for scanners to investigate. You should note that whenever a dwarf type entry challenges KotH, the scanners drop down somewhat. CMP scanners tend to be big (this is a very relative term) with lots of critical locations. A bomber like PitTrap only has 3 code locations and 1 critical data location. Charon has 11 code locations and 2 data locations. Finally, you cannot (as far as I could think) make a self-splitting scanner.

One last thing I want to note is that I've been experimenting (as have Nandor Sieben and Andy Pierce, I imagine) with a scan that has a location/cycle ratio of 1/1. Here is a model:

search  add inc, target
target  cmp START+DIST, START
        jmp gotem
        jmz search, <target

        ...

inc     dat #STEP, #STEP+1

I have not been able to come up with anything worthwhile. The best test of this method went to 10th on KotH before I removed it.

I hope all this helps.

NOTE: REMEMBER that while scanning you will most likely come across your OWN code. The SLT instruction is a great tool to use in avoiding this problem... A really cool way to use it was developed by Stefan Strack (and used in Charon v3.0 and beyond):

search  add inc, target
target  cmp START, START+DIST
        slt #LENGTH, target
        jmp add

        ...