Comparison between signed variables in PIC18 assembly

roxi60

Joined Sep 2, 2018
73
Hello.
The code below compares a 16 bit and an 8 bit variable.
What is not clear to me is the part after the bz diff, where xorwf and xorlw 128 are used.
What is their function?
Any suggestion\clarification on the working principle of this algorithm would be appreciated.

Regards

Code:
; A is a 2 byte signed variable (AH A)
; B is a 1 byte signed variable (B)
; IF A>B THEN trueif
movlw 0
btfsc B,7
movlw 255
subwf AH,W
bz diff
movf AH,W
xorwf B,W
btfsc STATUS,0
xorlw 128
andlw 128
bz restofcode
bra trueif
diff
movf A,W
subwf B,W
bc restofcode
trueif
;...
restofcode
;...

BobaMosfet

Joined Jul 1, 2009
1,910
Hello.
The code below compares a 16 bit and an 8 bit variable.
What is not clear to me is the part after the bz diff, where xorwf and xorlw 128 are used.
What is their function?
Any suggestion\clarification on the working principle of this algorithm would be appreciated.

Regards

Code:
; A is a 2 byte signed variable (AH A)
; B is a 1 byte signed variable (B)
; IF A>B THEN trueif
movlw 0
btfsc B,7
movlw 255
subwf AH,W
bz diff
movf AH,W
xorwf B,W
btfsc STATUS,0
xorlw 128
andlw 128
bz restofcode
bra trueif
diff
movf A,W
subwf B,W
bc restofcode
trueif
;...
restofcode
;...
In assembly language (any processor), the only value that exists is zero. There is zero, and anything other than zero. How a processor compares to zero is it subtracts one value from another and compares that with zero. Because, again, zero is the only value it knows of with precision.

bz is your comparison and branch based on zero.

Hopefully this will help:

https://owd.tcnj.edu/~hernande/ELC343/Chapter_02.pdf

Last edited:

roxi60

Joined Sep 2, 2018
73
Thank you, BobaMosfet.
I know.
I think the first part (up to bz diff) is the check if the 2 operands have the same sign and are only one byte.
What I don't understand is why I need the xorwf and xorlw 128 andlw 128, if the signs are different.
In other word, what's the algorithm that stays after this code.
Furthermore, why there's a comparison between the high byte of A and the byte B.

Thank you.

atferrari

Joined Jan 6, 2004
4,506
In assembly language (any processor), the only value that exists is zero. There is zero, and anything other than zero. How a processor compares to zero is it subtracts one value from another and compares that with zero. Because, again, zero is the only value it knows of with precision.

bz is your comparison and branch based on zero.

Hopefully this will help:

https://owd.tcnj.edu/~hernande/ELC343/Chapter_02.pdf
Not sure that I could try to discuss this but I always felt that the sole two conditions that leave no doubt in a byte are zero or all bits set. Not sure I said.

Additional comment: never found the occasion where I would need to compare 8-bits number with a 16-bits number or viceversa. It makes no sense to me.

BobaMosfet

Joined Jul 1, 2009
1,910
Thank you, BobaMosfet.
I know.
I think the first part (up to bz diff) is the check if the 2 operands have the same sign and are only one byte.
What I don't understand is why I need the xorwf and xorlw 128 andlw 128, if the signs are different.
In other word, what's the algorithm that stays after this code.
Furthermore, why there's a comparison between the high byte of A and the byte B.

Thank you.
...and I ask, why don't you create a flow chart of the logic? It will become clear as to why, then.
...and here is the official reference:

You also need to clarify- are 'AH' and 'A' different variables, or are you saying A is also the equivalent of AH? Since you didn't specify, I assumed they are different. Here's a flowchart (based on your code): Last edited:

Papabravo

Joined Feb 24, 2006
17,529
My default assumption is that this will compare AH,A to a sign extended version of B where the equivalent of BH is either all zeros or all ones. I agree that it doesn't make a whole lot of sense, but that was not the original question. A signed 8 bit quantity represents numbers from -128 to +127. Outside this range the answer is obvious by inspection. So inside the range is where it matters.

jpanhalt

Joined Jan 18, 2008
11,088
@BobaMosfet
That flowchart simply repeats what the mnemonics do. It does not describe the logic.

1) The program does simulate.
2) I view it as sort of a sorting protocol:
a) Steps 4-8 find whether both variables are one byte. If so, it branches to "diff" to get the result.
b) After those steps, we know that A is 2 bytes. Therefore, if A is positive and then A > B; or if A if is negative then A < B

BobaMosfet

Joined Jul 1, 2009
1,910
@BobaMosfet
That flowchart simply repeats what the mnemonics do. It does not describe the logic.

1) The program does simulate.
2) I view it as sort of a sorting protocol:
a) Steps 4-8 find whether both variables are one byte. If so, it branches to "diff" to get the result.
b) After those steps, we know that A is 2 bytes. Therefore, if A is positive and then A > B; or if A if is negative then A < B
Yes, it does, but worded at slightly higher level than just mnemonics. My goal was to help them view it in another way to help them solve it, not just do the work for them. If the TP can't understand it then they have an insufficient understanding of the mnemonics and need to spend more time reading the documentation (which is why I supplied a link).

roxi60

Joined Sep 2, 2018
73
Hello.
First of all, thank you very much for your kind answers, BobaMosfet, atferrari, jpanhalt, Papabravo.
All of them were useful to me and I appreciated them a lot!
It seems stupid, but when something is not clear in your mind, it’s a sort of little pain, and these answers helped me a lot.
Somewhere else I had no answer at all for that, for instance, so many thanks again.

Let’s explain better the aim and clear what I understood till now.

1) I know the basis of mnemonics and their use. My aim here was to understand the logic, as jpanhalt said and started to explain. What’s the better logic if I want two compare two signed numbers in PIC assembly language? So I started with this code I found in literature.

2) Variable A is a signed word (so it occupies two bytes : AH is the higher one and A the lower one). So AH= Ahigh and A= Alow.
Sorry, I know, it would be better if I used AH and AL instead. It wouldn’t be so confusing.
Variable B is a signed byte.
Comparison of 8-bit with 16-bit may have sense if you want to spare memory, I suppose (if variable B is in a range that does not need it, why to use a 16-bit?).
Anyway, don’t know, I found it so and I’m trying to understand the logic of this piece of code, because I guess it’s quite complete and useful to understand how assembly logic works.

Now let’s come to what I understood till now and what not.

3) Steps 4-8 .
Bit 7 of B is checked (sign of B):
-if variable B is negative, W= 255 and AH-W = 0 only if AH=255, that means variable AHA also negative and one byte.
-if variable B is positive, W= 0 and AH-W = 0 only if AH=0, that means variable AHA also positive and one byte.
So bz diff is true only if both variable are 8-bit and same sign (not only 8-bit), that allows check of inequality according steps16-19.

4) Steps 9-15
This is the part the logic of which is hard to me to understand.
Here I come in all other cases other than “8-bit same sign”.
It seems that there are two checks.

One
9 movf AH,W
10 xorwf B,W
check for the equality of signs of B and AHA:
-if they are equal, bit 7 of WREG is 0
-if they are unequal, bit 7 of WREG is 1

Two
11 btfsc STATUS,0
check for the carry bit, as results from
7 subwf AH,W
According to the result of this latest check in 11 step, it seems
if carry =1, the bit 7 of W is first inverted and then W is masked to take only bit 7
if carry=0 W is masked to take only bit 7 as it is.

So my trouble is to understand the logic that stays in the background of these two checks, when the signs of the two operands is not the same or when the AHA operand is 16-bit.

Please tell me also if my assumptions are wrong.

Thank you again

Regards

jpanhalt

Joined Jan 18, 2008
11,088
Comparison of 8-bit with 16-bit may have sense if you want to spare memory, I suppose (if variable B is in a range that does not need it, why to use a 16-bit?).
Anyway, don’t know, I found it so and I’m trying to understand the logic of this piece of code, because I guess it’s quite complete and useful to understand how assembly logic works.
That may make sense if only one signed variable is 16-bit. In reality, that seems unlikely, so the hypothetical saving of one user RAM byte probably doesn't exist. In contrast, one may have to make both 16-bit to 16-bit comparisons and every combination of 8-bit to 16-bit comparisons. For compactness, it is probably better to have a single 16-bit comparison that handles anything up to 16 x 16 bit, assuming you are using it as a call, not in-line code.

Same advice applies to other called routines such as division, multiplication, and BIN2ASCII. The exception might be in-line routines like addition and subtraction that are very short and can be tailored to the specific need at the point of use. Some coders use macros for those functions. That doesn't save code space, but can make writing and reading the code easier.

In the future, please post commented code. If it is code you got somewhere else, remember it is copyrighted at the time of its creation and you should give the source. You can still post your comments on copied code, but be sure to indicate whether the comments are yours or the originator's.

As for those steps you still wonder about, show your best effort at solving them. It appears this thread, your LCD monitor thread, and other threads are learning exercises for you. One might consider them"Homework." But even if not homework, you will benefit much more if you spend time trying to solve them, then asking more restricted questions.

BobaMosfet

Joined Jul 1, 2009
1,910
One thing that can help, although it seems non-obvious is to go through the algorith with actual values in each register, and keep track of the flag bits on paper (or on the flow-chart) as you walk through it- this alone can help you understand why and what.

• atferrari

roxi60

Joined Sep 2, 2018
73
That’s the explanation I was looking for.

1) Steps 4-8 .
Bit 7 of B is checked (sign of B):
-if variable B is negative, W= 255 and AH-W = 0 only if AH=255, that means variable AHA also negative and one byte.
-if variable B is positive, W= 0 and AH-W = 0 only if AH=0, that means variable AHA also positive and one byte.
So bz diff is true only if both variable are 8-bit and same sign (not only 8-bit), that allows check of inequality according steps16-19.

2) Steps 9-15
Here I come in all other cases other than “8-bit same sign”.
At this point, the inequality is true if AH >=0. Because if it is >0 two bytes are greater than 1 byte, and if it is 0, a positive 8 bit is greater than a negative one (since equal signs has already been checked before).
For that, checking only the carry C as in step 4-8 is not enough, since there I can have C=0 with AH both positive and negative, in the range 0<AH<255, and the same if C=1.
That’s way I need an additional check, the one in step 9 and 10:
9 movf AH,W
10 xorwf B,W
check for the equality of signs of B and AHA:
-if they are equal, bit 7 of WREG is 0
-if they are unequal, bit 7 of WREG is 1

Conclusion is:
From check of the carry bit C as it results from step7 (subwf AH,W):
11 btfsc STATUS,0
I can have:
C=0, from step4-8 means B negative (so AH >= 0 when bit 7 of WREG is 1 in step 10)
C=1, from step4-8 means B positive (so AH >= 0 when bit 7 of WREG is 0 in step 10)
In steps14-15:
14 bz restofcode
15 bra trueif
the not-zero condition is checked for trueif in this way:
-when C=0 I take bit 7 of WREG as it is (only masked WREG with “andlw128”)
-when C=1 I need to invert bit 7 of WREG and then mask WREG to have not zero (with both “xorlw 128” and “andlw 128”).
In that way if I have WREG 1 (not-zero) I’m sure AH >= 0.

NOTE: maybe (I’m not sure if it covers all cases) steps 9-15 might be replaced by:

btfss AH,7
bra restofcode
bra trueif

that simply checks the sign of AH.

-This piece of code is taken from a disassembled high language, so I don’t think I’m going to infringe any copyright, taking also into account that I ‘m not using it for commercial purpose.
-This comparison study in assembly is still a part of mine main hobby project, that is to plot acquired data on a GLCD by scrolling the line with new data, all done in PIC assembly language, because that is a quite complete job to better to understand how microcontrollers work. Comparison is needed in Bresenham’s algorithm. So my questions are linked with a common aim, they are unconnected questions.
I didn’t find at the moment nothing like that in web (all is in high level language, but it would be easier and not so instructive).
-Going into details and asking, like I did till now may appear boring, but that’s not my opinion. I tried to ask only after days and days of attempts to understand, that brought to nothing.
Learning is in details, one must be boring for that.
I’m aware that that can be disturbing and time wasting for many, so I’ll stop posting.

Regards

jpanhalt

Joined Jan 18, 2008
11,088
btfss AH,7
bra restofcode
bra trueif
Since you know at that point that AH = 0, then condition "If A>B then true if" would be met when A is >0 (i.e., positive). If bit<7> of AH is set, then it's negative.

So, I think you want:

btfsc AH,7
bra restofcode
bra trueif

EDIT: I am not sure about the copyright matter on a disassembly of something in C, but it is polite to always give the source of code you copy.

John

Last edited: