3. The CMP Instruction Family

While all this talk of moving data around, be it in memory or within the processor's internal registers, is 'interesting', being able to move data is not much use if you cannot do anything with it when you have moved it. As the condition codes are affected by data movements we can sometimes determine the value of the data we moved. This is of course true only if we want to know if the value we moved was zero, or not zero, positive or negative but that's about as accurate as we can get using the MOVE instruction.

If we need to compare two values we will need to use the CMP family of instructions. CMP stands for 'Compare' and allows data to be compared against specific values, registers or memory contents.

The general format of the CMP instruction is :

CMP.size    source,destination

The CMP instruction has the effect of carrying out a subtraction of source from destination without changing the destination at all. What it does change is the condition codes, and these will be set as follows :

This instruction can be carried out in all three sizes - byte, word or long.

One of the common uses of this instruction, and perhaps the easiest to understand, is testing to see whether two values are the same. If they are then the result of the 'subtraction' of source from destination will always be zero. If the result is zero then the Z flag can be tested (somehow - we shall see later) and then some actions taken if it is set while others can be taken if it is not set.

The instruction :

CMP.L    D1,D2

Will set the Z flag if the same value is present in both D1 and D2. If they are different, then the Z flag will not be set.

There are only four variations of the CMP instruction - unlike MOVE which has a few more. The first is simply CMP itself. This is used when comparing with a data register as in the above example. The source, however, can be any of the 68000 addressing modes - although you cannot compare an address register and a data register using the BYTE size. This means that :

CMP.W    A0,D2 

is a legal instruction, but that :

CMP.B    A0,D2

Is not. It is of course allowed that the data be POINTED to by an address register, as in :

CMP.B    0(A0),D2

Which compares the byte of data at the address held in A0 with the byte of data held in the lowest byte of register D2.

CMPA - is the form of the instruction used when comparing against a destination which is an address register. It is very similar to the CMP variation, but only word and long sized comparisons can be made. If the word size is used, then watch out for the old favourite pitfall of sign extension. Whatever word sized data is used for the source of this comparison will be sign extended up to a long word and then compared with the entire 32 bits of the address register.

This means that :

CMPA.W    #$FFFF,A3

Would set the Z flag if and only if A3 contained the value of $FFFFFFFF but would not set it if A3 contained the value $0000FFFF. Beware. If at all possible, make your code explicit. SO if you want to test A3 as having $FFFF in its lower word, use CMPA.L #$FFFF,A3 instead of the word sized version.

CMPI - is the third variation and this one is used when testing any address mode destination (except PC relative or an address register's contents) against souce data which is, quite simply, a number. This variation can be used in all 3 sizes. The format of the instruction is :

CMPI.size    #data,destination

If the destination is a data register, then the instruction is equivalent to the CMP instruction.

CMPM - is the final variation. It is used to compare one memory location with another. It can be used in all 3 sizes but can only be used in a single address mode - address register with postincrement. The format is always :

CMPM.size    (An)+,(An)+

The two address registers are pointers to the memory addresses to be compared and after this instruction, the flags have been set according to the result of the 'subtraction' while both address registers have been incremented by 1, 2 or 4 depending upon the size of the data being compared.