Thread: C code to use the carry flag (sbb/jnc)

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    1

    C code to use the carry flag (sbb/jnc)

    Hi.

    I am trying to optimize some code that I use in a loop. I have an unsigned int and I test the left most bit to decide whether to take some action, then shift the remaining bits to the left. Right now I use:

    Code:
    unsigned int tempbc; // previously filled with bits to process
    unsigned int val1, y;  // assigned elsewhere in the loop
    float val2; // assigned elsewhere in the loop
    
    // start loop
    
        if ((int)tempbc < 0)
            val1 -= y;
        tempbc += tempbc;  // shift 1 bit to left
    
    // do some other stuff
    
        if ((int)tempbc < 0)
            val2 += y;
        tempbc += tempbc;  // shift 1 bit to left
    I'm using MSVC and when I compile my code, it produces a test of tempbc with a conditional jump based on the sign followed by the add for tempbc. I'd really like to somehow change the code so that I can do the tempbc += tempbc first and then test or manipulate the carry flag but I can't come up with code to make this happen. (I don't want to use inline assembly because it is a complicated function and I'd like the code to be as portable as possible.)

    This is some pseudo-assembly code for what I'd like the end result to be.

    For the first case:
    Code:
        add tempbc, tempbc
        sbb dummyreg, dummyreg  // -1 if carry flag set in add, 0 otherwise
        and dummyreg, y
        sub val1, y
    For the second vase:
    Code:
        add tempbc, tempbc
        jnc LABEL_NEXT
        fisub y
    LABEL_NEXT:
    Hopefully that psedocode helps you understand what I'm trying to accomplish. Any suggestions?

    Kmart

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I suspect that you cannot directly "test or manipulate the carry flag" in C without the use of inline assembly as C does not have the concept of a carry flag. It just stipulates the net effect of what happens when arithmetic on unsigned integers would otherwise result in an overflow.

    In the interest of portability, you might want to note that the result of (int)tempbc is implementation defined if the value of tempbc is not in the range of an int (yet that is precisely what you are checking for). Perhaps you should test for tempbc & (1U << (sizeof(tempbc) * CHAR_BIT - 1)).

    That said, your main aim is probably to avoid the conditional jump, and perhaps this will do it:
    Code:
    /* ... */
    const unsigned int shift_amount = sizeof(tempbc) * CHAR_BIT - 1;
    
    /* start loop */
    
        val1 -= ((tempbc & (1U << shift_amount)) >> shift_amount) * y;
        tempbc += tempbc;
    
        /* ... */
    
        val2 += ((tempbc & (1U << shift_amount)) >> shift_amount) * y;
        tempbc += tempbc;
    On the other hand, it also introduces other operations that may lead to no net advantage. Remember to compile with optimisations turned on when comparing, and of course to check if there is any observable effect when actually running the program.
    Last edited by laserlight; 02-27-2010 at 02:59 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Proposal: Code colouring
    By Perspective in forum A Brief History of Cprogramming.com
    Replies: 28
    Last Post: 05-14-2007, 07:23 AM
  2. Explain this C code in english
    By soadlink in forum C Programming
    Replies: 16
    Last Post: 08-31-2006, 12:48 AM
  3. Updated sound engine code
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 11-18-2004, 12:38 PM
  4. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM