Section 06 Part 02 – The CMP, TST & BTST Instructions

 

“What lies behind you and what lies in front of you, pales in comparison to what lies inside of you.~Ralph Waldo Emerson

 

 

 

Introduction

 

These instructions test the destination operand for certain conditions, and set the CCR flags accordingly.  The destination operand in these cases remains unchanged though.

 

 

 

The CMP Instruction

 

CMP - CoMPare

 

The source operand is subtracted from the destination operand to get the CCR conditions.  The destination operand is not changed however.

 

 

 

Examples

 

You’ve seen CMP used before in the previous part:

 

          cmpi.w    #$0F20,d0

 

We’ll pretend that d0 contains FF940F21.  Since the instruction is .w for word, only the 0F21 is compared with.  The way the CMP instruction gets its results is by subtracting the source from the destination, but without saving the result.  So 0F210F20 = 0001.

 

Now, it sets the flags:

 

 

After this instruction d0 will still contain FF940F21, but now the CCR flags are set, and can be used.

 

Once again, you’ll notice in the example the CMP instruction had “i” for immediate, ensure you use “i” for immediate values (though once again, your assembler make take care of this for you).

 

You can compare using byte, word or long-word sizes.  The CMP instruction is capable of comparing between; data registers, address registers, memory addresses, memory using address registers, just to list the most common here.  It should be noted that address registers can not be compared using byte.

 

 

 

The TST Instruction

 

TST – TeST an operand

 

The destination operand is compared with zero to get the CCR conditions.  The destination operand remains unchanged.

 

 

 

Examples

 

Here’s the instruction:

 

          tst.w     d0

 

Now this here is pretty much the same as:

 

          cmpi.w    #$0000,d0

 

The same flags are changed for the same reasons.  Except obviously, the V and C flags will always end up being cleared here.

 

This instruction is smaller and quicker than using the CMP instruction, so in cases where you need to check for zero.  It is recommended to use the TST instruction for optimal reasons.

 

 

 

The BTST Instruction

 

BTST – TeST a Bit

 

This instruction will test the bit number in the destination operand decided by the source operand.  The result is saved to the Z flag.

 

 

 

Examples

 

If you remember back in Section 03 Part 05 we looked at BSET, BCLR and BCHG.   This instruction works in the same way, the source operand and destination operand are restricted in the same way (i.e. the source can only be an immediate value or a data register, data registers are long-word operated while other modes are byte operated, etc).

 

The difference here is the bit number is not changed, instead it is simply tested to see if it is set (1) or clear (0):

 

          btst.l    #$03,d0

 

In this example, bit 03 in data register d0 is checked.  We’ll pretend that d0 contains 7FF290F5, in binary that’s:

 

Binary contents inside d0 (with position number above)

 

1F

1E

1D

1C

1B

1A

19

18

17

16

15

14

13

12

11

10

0F

0E

0D

0C

0B

0A

09

08

07

06

05

04

03

02

01

00

0

1

1

1

1

1

1

1

1

1

1

1

0

0

1

0

1

0

0

1

0

0

0

0

1

1

1

1

0

1

0

1

 

As you can see, bit 03 is clear (0), and since it’s zero, the Z flag of the CCR is set.

 

Here’s another:

 

          btst.l    #$11,d0

 

Again, d0 contains 7FF290F5:

 

Binary contents inside d0 (with position number above)

 

1F

1E

1D

1C

1B

1A

19

18

17

16

15

14

13

12

11

10

0F

0E

0D

0C

0B

0A

09

08

07

06

05

04

03

02

01

00

0

1

1

1

1

1

1

1

1

1

1

1

0

0

1

0

1

0

0

1

0

0

0

0

1

1

1

1

0

1

0

1

 

Here, bit 11 is set (1), and since it is not zero, the Z flag of the CCR is cleared.

 

 

 

Summary

 

These instructions are used to set the CCR flags when needed; you’ll often be using them with a condition branch instruction (e.g. the BEQ instruction).  Though it is important to note that the 68k is quite a unique architecture, being orthogonal, many instructions will set, clear, or change the CCR flags anyway.  For example:

 

          add.b     d1,d0

          tst.b     d0

          beq.s     ValueIsZero

 

In this case, a byte of d1 is added to a byte of d0.  d0 is then checked to see if it is zero.  The BEQ instruction will then branch to the lable ValueIsZero if the result is zero, if it is not, it’ll continue.

 

The thing is, the ADD instruction sets the CCR Z flag anyway.  So you could remove that TST instruction and leave only the ADD and the BEQ:

 

          add.b     d1,d0

          beq.s     ValueIsZero

 

And it’ll function just the same, except now you’re using less instructions, it’s smaller, and slightly faster.

 

 

 

Previous Part

Main Page

Next Part