This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

programming code

can anybody translate the assembler code below in C.

          rrc    X                      ; rotate right through c

          jc      A                      ; jmp to A if carry is set (status register bit 0)

 

appreciate it.

  • Hi,

     

    Maybe something like this??

     

    A:

      if ((X & 0x01) == 0x01) goto A;

     

    Best regards,

    AES

  • The original c is lost by c. It is hopeless.

    (The first c is for the carry, the second c is for the language.)

  • old_cow_yellow said:
    The first c is for the carry, the second c is for the language.

    It#s a big language, so you can give it a big 'C' :)

    Indeed, things like carry bits are not inside the scope of the C language. C is machine independent, and a carry bit is a machine dependent concept.
    YOu usually need a rotate-through-carry to concat several machine registers (too a machine-dependent thing) to form larger-sized datatypes.
    Such as shifting a long int variable that is contained in two 16 bit registers.
    Normally, oonly CRC algorithms require a carry of some sort. But then, most require more than one carry bit (standard CCITT algorithm has 4) :)

    But you can simulate it.

    carry=x>>n; // n is bitwidth of x
    n<<=1;
    n|=carry;
    if(carry)...

  • I think we need some context for the code fragment. A literal translation or simulation would be excessive if the intent was to quickly destructively test "x" for bit 0. Simulating the HW leads to a "Rube Goldberg" level of complexity for doing a simple thing.

    int status = 0; /* Simulated status register */

    /* Assumes "int" is 16 bits */
    int rrc(int x)
    {
      int c;
      int m;
      c   = status & 0x0001; /* Get carry bit. 0 or 1 */

      m   = c<<15;           /* Make the most significant bit mask */
      c   = x & 1;           /* Calc carry out. 0 or 1 */
      x >>= 1;               /* Logical shift right. Zero shifted in on left */
      x  |= m;               /* Set top most bit with carry in */

      status |= c;           /* Update the carry bit in status */
                             /* Update N and Z bits too? */
      return(x);
    }

    void loop16times(void)
    {
      int x = 0xFFFF;
      status = 0; /* Clear everything, including carry */
    A:
      x = rrc(x);
      if(status&0x0001) goto A;
    }

    That was fun.

  • thanks everybody, I found it by myself, here is the answer:

          X >>= 1;

          if (__get_SR_register()  &  BIT0)  goto A;

     

  • huong tovan said:
       X >>= 1;
          if (__get_SR_register()  &  BIT0)  goto A;


    this is dangerous and maybe only workign by coincidence.

    There is no guarantee that the carry bit will survive between two C instructions. The shift may have been done many instructions before due to optimizing. Or will be done after the __get_SR_register instruction (unlexx X is volatile, then it will be definitely be done before, but not sure when before).

    Besides the fact that goto is goto is dangerous to use (and its use usually is a sign of an application flow design flaw) and should be replaced by if/while/for/do constructs, the correct code for this problem is

    if(carry) {
      carry = x&1;
      X>>=1;
      X|=0x8000;
      goto A;
    } else {
      carry=X&1;
      X>>=1;
    }

    Despite looking longer at first, the compiler may still optimize it to the very assembly code you originally had. (If it is clever enough)

     

  • Either way, the original carry bit is not shifted to the msb of X. It is lost forever. C cannot handle c.

    "rrc X" in assembly rotates the original carry bit to the msb of X.

    "X>>=1;" in C does it differently. It is translated to "rra X" in assembly which copies the original msb of X to the new msb of X.

  • old_cow_yellow said:
    Either way, the original carry bit is not shifted to the msb of X

    There is no 'original carry bit' in C. As there is no carry bit in C. You need to preserve it yourself.

    I have modified my previous post to reflect the carry.

    old_cow_yellow said:
    "X>>=1;" in C does it differently. It is translated to "rra X" in assembly which copies the original msb of X to the new msb of X.

    Only if X is a signed int. For unsigned int, it shifts-in a '0' to MSB position.

**Attention** This is a public forum