Compare Operations

Introduction

Compare operations use the subtract command.

I have found the use of the subtract command to be somewhat confusing in two respects. The subtraction seems backward and the result of the status of the Carry seems reversed from what I would have expected.

I found it useful to think in terms of comparing a number with 2. Note that the two's compliment of 2 is FEH. Thus, I can puzzle through my code using 2 and then simply modify it to 25 or 100 or whatever.

Equality.

Assume one is attempting to determine if a quantity is equal to 2.

	MOVLW .2
	SUBWF Q, W	; W = Q - 2
	BTFSS STATUS, Z
	GOTO NOT_EQ
	GOTO EQ

Note that the quantities are subtracted with the result saved to the W register to avoid destroying variable Q and the Zero flag in the Status register is tested. Note that when executing the SUBWF (or SUBLW) command that;

	W = Q - W

Greater Than and Less Than.

Consider the following;

	MOVLW .2
	SUBWF Q, W	; W = Q - 2
	BTFSS STATUS, C
	GOTO PLACE_1
	GOTO PLACE_2

My incorrect assumption would be that if Q is less than 2, a borrow will occur and thus the Carry flag will be set and the program with branch to PLACE_2. As I say, this is incorrect. Too many years using the 68HC11!

Rather, in performing the subtraction, the 2 is changed to two's compliment (FEH) and this is added to Q. Thus, if Q is less than 2, there will be no carry and the program will branch to PLACE_1.

Thus, so far we know that if Q < 2 then the program goes to PLACE_1.

If Q is equal to 2, the subtraction is implemented as 2 + FEH. Note that a carry does occur and thus on equality the program branches to PLACE_2.

Thus, the above code;

	Q < 2	PLACE_1
	Q >=2   PLACE_2

But, what if we wanted the program to go to one place if Q <= 2, we could turn the subtraction around;

	MOVF Q, W
	SUBLW .2	; W = 2 - Q
	BTFSS STATUS, C
	GOTO PLACE_1
	GOTO PLACE_2

If Q is 1, the subtraction is implemented as 2 + FF. A carry occurs. Thus, if Q < 2, the program branches to PLACE_2.

If Q is equal to 2, the subtraction is 2 + FE. A carry occurs. Thus, if Q = 2, the program is redirected to PLACE_2.

If Q is 3, the subtraction is 2 + FD. No carry occurs. Thus, if Q > 2, the program branches to PLACE_1.

After going through the above, a natural impulse is to resolve never to compare anything, which is ridiculous or resolve to always use some sort of a table.

I would encourage you to take neither position, but, rather, when confronted with a compare operation, to write the code even if it is incorrect. (Somehow our educational system fails to offer that this is a valid approach). Then puzzle through its operation using numbers you understand such as 1, 2 and 3. If your first walk through doesn't do what you want, turn around the order of the subtraction.

One Final Puzzlement.

Consider the above example;

	MOVF Q, W
	SUBLW .2	; W = 2 - Q
	BTFSS STATUS, C
	GOTO PLACE_1
	GOTO PLACE_2

We previously argued that if Q was 1, the subtraction is implemented as 2 + FE and a carry occurs and thus the program branches to PLACE_2.

But, clearly the same should be true if Q is 0. But as the two's complement of 0 is 0, the subtraction is implemented as 2 + 0 and no carry occurs. But, wait a minute! That's not correct. Perhaps the two's complement of 0 is 100H. That is, 00 with a carry of 1 and the subtraction is implemented as 2 + 100H. I haven't seen any documentation on this, but assume the two's complement of 0 is 100H.