Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
07/26/00 14:37
Read: times


 
#3994 - Range Comparison on the 8051
This is about UNSIGNED comparisons:
= = = = = = = = = = = = = = = = = =

Sascha's method is the way to do GT/EQ/LT determinations. If you need only EQ/NEQ then the CJNE instructions are reasonable.

If you are looking for a relative companison of GT/EQ/LT you must first do a comparison to divide the outcomes into two classes such as: {GT+EQ vs LT} or {GT vs EQ+LT}.

After the initial comparison and jump you can often quickly determine the EQ case as a zero in the accumulator and jump to separate the pair of cases that dropped through the initial comparison. If you use a limit offset, a CJNE can be used to distinguish the EQ case.

For example, say I want to compare R7 against 100d and branch to routines GT, EQ, LT based on the result:

. ;{GT vs EQ+LT}:
. clr cy ;trick below eliminates this
. mov a,#100d ;limit point
. subb a,r7 ;subtracting >100 sets cy
. jc GT ;jump if cy, dropthru if EQ+LT
. jz EQ ;100d-100d yields Zero if EQ
LT: ;else value less than 100d
...
EQ:
...
GT:
...
.end example


. ;{LT vs EQ+GT}:
. ;the 100d-1 is converted to 99d at compile time.
. ;writing it out documents your intent
. clr cy ;trick below eliminates this
. mov a,#100d-1 ;minus 1 forces EQ with QT to set CY
. jc GTEQ ;jump if 100 or higher
LT:
...
GTEQ:
. cjne a,#100d-99d,GT ;jump if value-99d more than 1
EQ: ;else value equals 100d
...
GT: ;here if value greater than 100d
...
.end example


A little trick:
- - - - - - - - - - - - - -
Sascha's method is good. You can save the step of clearing the carry if instead you add the equivalent positive value that separates the two outcome classes into distinct CY flag results. Its a little trickier to think what the right value is and then the correct jump but its a little quicker. Make sure you write documentation on the instructions so someone else won't later think that its a mistake.

What you're actually doing instead of a CLR CY + SUBB instruction is using an ADD with a value negative in one or two's complement form, whichever is appropriate.

If you use this step, document your intent and test your routine. Often someone later checking the code will be confused and attempt to rewrite this method... I include warnings advicing them that if they think its wrong, go tell their boss they need more training. :)

.;{GT+EQ vs LT}:
. mov a,#100h-100d ;limit complement
. add a,r7 ;100d or higher sets cy
. jnc LT ;jump if no cy, else GT+EQ
. jz EQ ;100h-100d+100d yields Zero if EQ
GT: ;else value greater than 100d
...
EQ: ;here if 100d
...
LT: ;here if less than 100d
...
.end example

Here, #9Ch + 64h (100d) = 100h yielding CY and a ZERO accumulator.


-Jay C. Box


List of 15 messages in thread
TopicAuthorDate
"Smaller then" "Greater then"            01/01/70 00:00      
RE: "Smaller then" "Greater then&qu            01/01/70 00:00      
RE: "Smaller then" "Greater then&qu            01/01/70 00:00      
RE: "Smaller then" "Greater then&qu            01/01/70 00:00      
RE: "Smaller then" "Greater then&am            01/01/70 00:00      
Range Comparison on the 8051            01/01/70 00:00      
Range Comparison on the 8051            01/01/70 00:00      
RE: Range Comparison on the 8051            01/01/70 00:00      
RE: Range Comparison on the 8051            01/01/70 00:00      
RE: "Smaller then" "Greater then&qu            01/01/70 00:00      
RE: "Smaller then" "Greater then&am            01/01/70 00:00      
RE: "Smaller then" "Greater then&am            01/01/70 00:00      
RE: "Smaller then" "Greater then&am            01/01/70 00:00      
RE: "Smaller then" "Greater then&am            01/01/70 00:00      
END OF THREAD            01/01/70 00:00      

Back to Subject List