8051 assembly language help

Thread Starter

leonhart88

Joined Feb 23, 2007
118
Hi everyone, i want to compare a number in a register to see if its equal to or greater than a number.

For example i want to see if R1 is >= 60, i have a programming guide but i dont really understand what it is saying

CJNE R7,#60H,NOT_EQ
; ... .... ; R7 = 60H.
NOT_EQ JC REQ_LOW ; IF R7 < 60H.
; ... .... ; R7 > 60H.

it says something like this and it says by testing the carry flag it can determine whether is it greater or smaller than 60H. Im quite new to assembly language so if someone could explain this to me simply i would really appreciate it.

Also, how would i compare a number stored in 3 registers.. say R1-R2-R3? Say if i wanted R1-R2-R3 >= 60?

thanks!
 

Papabravo

Joined Feb 24, 2006
21,159
You have to take a step back and examine your understanding of binary arithmetic. The data registers and memory in an 8051 are 8 bits wide. Such a data register can represent EITHER an unsigned quantity in the range [0..255] OR a signed quantity in the range [-128..127]. When doing comparisons it is important to understand the difference. Unsigned comparison is done by binary subtraction. Binary subtraction can be done by adding the twos complement, and complementing the carry bit to get the BORROW condition. Let us start with an unsigned comparison, and take 3 cases
Rich (BB code):
CASE I - R7 == 65H
Step 1. 65H - 60H = 65H + A0H ; A0H is the 2's complement of 60H
Step 2. 65H + A0H = 05 && carry out of the MSB
Step 3. Complement Carry = 0 => No Borrow => 65H > 60H
 
CASE II - R7 == 55H
Step 1. 55H - 60H = 55H + A0H A0H is the 2's complement of 60H
Step 2. 55H + A0H = F5 && no carry out of the MSB
Step 3. Complement Carry = 1 => Borrow => 55H < 60H
 
Case III - R7 == 60H
Step 1. 60H - 60H = 60H + A0H ; A0H is the 2's complement of 60H
Step 2. 60H + A0H = 00H && carry out of the MSB
Step 3. Complement Carry = 0 => No Borrow
sTEP 4. No Borrow & Zero => 60H = 60H
You can now clearly see why the equal case must be eliminated before the carry test. I hope this helps.

To compare larger numbers you need to do a multibyte subtract and keep track of the BORROW. You may have noticed the ADDC (Add with Carry) instructions and the SUBB(Subtract with Borrow) instructions.
Try the following link for an 8051 Instruction set reference.
http://www.atmel.com/dyn/resources/prod_documents/doc0509.pdf
 

Thread Starter

leonhart88

Joined Feb 23, 2007
118
ok that helps a lot conceptually, thanks!

so if i have R0-R1-R2 and i want to find out if it is greater than or equal to say.. 600000.. then to do this i would put 600000 into 3 other registers, R3-R4-R5

and then i would use SUBB to subtract R2 with R5, and then R1 with R4 and then R0 with R3.. and if the borrow is 1 then the number in R0-R1-R2 was less than R3-R4-R5?

Also, there is a command JC i think.. it jumps if the carry is set. Are the carry and borrow flags the same? (it looks like the instruction manual refers to them as the same)
 

Papabravo

Joined Feb 24, 2006
21,159
The same flag is used for both addition and subtraction. In the case of subtraction if
C == 1 --> B == 0 and if
C == 0 ->> B == 1
because subtraction can be understood as adding the twos complement of the subtrahend.

In multiprecision arithmetic the operation on the least significant byte should be an ADD. The subsequent bytes should use and ADDC (Add with Carry). In the 8051 there is no ordinary subtract instruction so you have to set the first operation up by making the BORROW == 0 ( Carry == 1) prior to the operation on the least significant bytes.
 

Thread Starter

leonhart88

Joined Feb 23, 2007
118
if there is no ordinary subtract command, wont setting B==0 and then using SUBB perform the same action?

similarily if i set C=0 and use ADDC on the least sig. byte will that work like an ADD?

if not then i would have to add the twos complement of the least sig byte, and then i can carry on using SUBB with the next bytes correct?

also, you said before i perform the operation on the least sig byte, that i should set borrow == 0, which means set carry == 1. I read somewhere that if you use SUBB that you should always CLR C. Doesnt this mean clear the carry and make it 0? Doesn't this mean that the BORROW will initially be 1?

thanks
 

Papabravo

Joined Feb 24, 2006
21,159
The action of the SUBB A,Rn instruction is indeed:

(A) - (C) - (Rn)

So it would appear that in an SUBB instruction the Carry Flag acts like a borrow. Sorry for the confusion. Since I can't do hexidecimal subtraction in my head I always use 2's complement addition and the sense of carry(borrow) is inverted. It's better to do it any way that's comfortable for you.
 
Top