8051 assembly language help

Discussion in 'Embedded Systems and Microcontrollers' started by leonhart88, Feb 23, 2007.

  1. leonhart88

    Thread Starter Senior Member

    Feb 23, 2007
    118
    1
    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!
     
  2. Papabravo

    Expert

    Feb 24, 2006
    10,157
    1,795
    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
    Code ( (Unknown Language)):
    1.  
    2. CASE I - R7 == 65H
    3. Step 1. 65H - 60H = 65H + A0H ; A0H is the 2's complement of 60H
    4. Step 2. 65H + A0H = 05 && carry out of the MSB
    5. Step 3. Complement Carry = 0 => No Borrow => 65H > 60H
    6.  
    7. CASE II - R7 == 55H
    8. Step 1. 55H - 60H = 55H + A0H A0H is the 2's complement of 60H
    9. Step 2. 55H + A0H = F5 && no carry out of the MSB
    10. Step 3. Complement Carry = 1 => Borrow => 55H < 60H
    11.  
    12. Case III - R7 == 60H
    13. Step 1. 60H - 60H = 60H + A0H ; A0H is the 2's complement of 60H
    14. Step 2. 60H + A0H = 00H && carry out of the MSB
    15. Step 3. Complement Carry = 0 => No Borrow
    16. sTEP 4. No Borrow & Zero => 60H = 60H
    17.  
    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
     
  3. leonhart88

    Thread Starter Senior Member

    Feb 23, 2007
    118
    1
    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)
     
  4. Papabravo

    Expert

    Feb 24, 2006
    10,157
    1,795
    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.
     
  5. leonhart88

    Thread Starter Senior Member

    Feb 23, 2007
    118
    1
    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
     
  6. Papabravo

    Expert

    Feb 24, 2006
    10,157
    1,795
    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.
     
  7. leonhart88

    Thread Starter Senior Member

    Feb 23, 2007
    118
    1
    ok thanks!

    and thank you very much for helping me with my questions, ive tested my program and it works!
     
  8. Papabravo

    Expert

    Feb 24, 2006
    10,157
    1,795
    I'm glad I was able to help
     
Loading...