compares two 16-bit numbers by subtraction and reports one of the three possible cases: n1 < n2; n1 > n2; and n1 = n2.
PBASIC's If...Then statement allows you to compare two numbers up to 16 bits in length and make a decision (jump to a program address) based on the outcome of the comparison. Parallax assembly language offers the same capability through its compare-and-jump instructions (cja, cjae, cjb, cjbe...), but these are limited to 8-bit values.
The subroutine Comp16 compares 16-bit numbers and reports the results through
the w register as follows:
0 n1 = n2 1 n1 > n2 2 n1 < n2
Since it performs its comparisons through w, it does not alter n1 or n2.
To use Comp16 as a replacement for PBASIC's If...Then, use either a compare-and-jump instruction or Branch to process the result returned in w. See Branch for a method of handling compound logic expressions.
To see Comp16 in operation, either run the program with the PSIM simulator, or connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run COMP16.SRC. When you apply power to the PIC, the LEDs will light up in the binary pattern returned by the comparison (in this case 01, where 1 represents a lit LED). Try various combinations of n1 and n2 to see the three codes.
; COMPARE n1, n2 ; Compares two 16-bit numbers by subtracting one from the other and reports the ; outcome by a code in the w register. Does not alter n1 or n2. Uses the status ; register bit PA2 to preserve the z flag from subtraction of the LSBs. If you ; adapt this code for use in PICs other than 16C5x series, make sure that this ; bit is available. If it isn't, use a bit in one of the file registers instead. Z_ = PA2 ; Unused status bit as extra Z flag. org 8 n1H ds 1 ; MSB of n1. n1L ds 1 ; LSB of n1. n2H ds 1 ; MSB of n2. n2L ds 1 ; LSB of n2. ; Device data and reset vector device pic16c55,xt_osc,wdt_off,protect_off reset start org 0 start mov !rb,#0 ; Outputs for LEDs. mov n1H,#0C8h ; Compare 0C836h to mov n1L,#36h ; 2575h. mov n2H,#25h mov n2L,#75h call Comp16 ; Call the subroutine. mov rb,w ; Show result on LEDs jmp $ ; Endless loop ; Upon return, a code in w will indicate the outcome of the comparison. ; If n1 > n2 then w = 1. If n1 < n2 then w =2. If n1 = n2 then w = 0. Comp16 clrb Z_ ; Clear aux Z bit. mov w,n2L ; w = n2L subwf n1L,0 ; w = n1L-n2L snz ; Copy z bit to Z_. setb Z_ mov w,n2H ; If n1L-n2L underflowed, jc :cont ; then increment n2H (same mov w,++n2H ; as decrementing n1H). snz ; If n2H overflows, n1 must be < n2 retw 2 ; so return with 2 in w. :cont subwf n1H,0 ; w = n1H-n2H sc ; If n1H underflows, n1<n2 retw 2 ; so return with 2 in w. jnb Z_,:cont2 ; By now we're sure n1'>=n2. snz ; If both z and Z_ are set, retw 0 ; both subtractions resulted in 0, so :cont2 retw 1 ; n1=n2. Otherwise n1>n2.