[Avrora] Question on binary subtraction

Urs Hunkeler urs.hunkeler at epfl.ch
Tue Jan 18 07:57:20 PST 2011


Hi,

I'm stuck again, and this time I have the exact location of the problem, 
but I don't understand what's going wrong. Maybe someone can help me here?

The C code of the problematic part looks like this (from 
TransformAlarmC.nc in TinyOS 2.x):

     if (remaining > MAX_DELAY)

The problem is that the body of the if-statement is executed even though 
at this point the variable "remaining" is 0, and the constant MAX_DELAY 
is 1024.

The corresponding assembly code (as obtained with the msp430-objdump 
tool) looks like this:

     42ce:       0c 48           mov     r8,     r12     ;
     42d0:       0d 49           mov     r9,     r13     ;
     42d2:       3c 80 01 04     sub     #1025,  r12     ;#0x0401
     42d6:       0d 73           sbc     r13             ;
     42d8:       17 28           jnc     $+48            ;abs 0x4308

So this means subtract 1025 (to have "greater" instead of "greater or 
equal") from "remaining" (which is 32-bits and stored in registers r8 
and r9). If the carry bit is not set, then do not execute the body of 
the if-statement (or, if the carry bit is set, then execute the body of 
the if-statement).

Since this is a subtraction with a negative result, I would expect the 
carry-bit to be set, but then the assembly code doesn't make sense. So 
maybe I misunderstand how the carry bit works?

In any case, the Avrora MSP430 interpreter (the part of the MSP430 code 
that has been available for a while on SF and probably has been written 
by Ben) performs the subtraction with the following outcome (as I would 
have expected):

     Sub: 0 - 1025 - 0 = -1025, C = true, N = true, Z = false, V = false
     Sub: 0 - 0 - 1 = -1, C = true, N = true, Z = false, V = false

And it then obviously executes the body of the if-statement, which 
results in the TinyOS timer code malfunctioning. This code works on real 
hardware. What is wrong here?

The subtraction code in the MPS430InstInterpreter class is the following 
(not written by me):

     public int performSubtractionW(int r1, int r2, int carry) {
         int result = r2 - r1 - carry;
     	boolean Rd15 = bit_get(r1, 15);
         boolean Rr15 = bit_get(r2, 15);
         boolean R15 = bit_get(result, 15);
         C = !Rd15 && Rr15 || Rr15 && R15 || R15 && !Rd15;
         N = R15;
         Z = low(result) == 0 && high(result) == 0;
         V = Rd15 && !Rr15 && !R15 || !Rd15 && Rr15 && R15;
         return result;
     }

Thanks for any help, comments or suggestions!

Cheers,
Urs


More information about the Avrora mailing list