Absolute value of signed constants inside a macro

Discussion in 'Embedded Systems and Microcontrollers' started by atferrari, Feb 14, 2011.

  1. atferrari

    Thread Starter AAC Fanatic!

    Jan 6, 2004
    2,648
    764
    PIC 18F family - Assembler
    There is a macro enabling, at compiling time, two other macros based on the sign of these parameters, ranging from 127 to -127
    Code ( (Unknown Language)):
    1.  
    2. CONSTANT PARAM0 -3
    3. CONSTANT PARAM1 124
    4. CONSTANT PARAM2 -56
    5. CONSTANT PARAM3 -7
    6. CONSTANT PARAM4 78
    7. CONSTANT PARAM5 -6  
    For that I used the expresion PARAM#v(i) where i is a local variable. So far, so good.

    My next (unsolved) problem is to get the absolute value of those constants to be used in further code inside the same macro. The solution has eluded me for the last three days.

    Any help appreciated.

    (Having the awful feeling that the solution is just in front of me)
     
  2. beenthere

    Retired Moderator

    Apr 20, 2004
    15,815
    282
    If all values are signed, then test for the MSB being set. If it is, convert to a positive number by zeroing the MSB. You can skip the test and simply clear the MSB, for that matter.
     
  3. Papabravo

    Expert

    Feb 24, 2006
    10,144
    1,791
    This only works for numbers in sign-magnitude representation. In 2s complement notation you can't get the additive inverse by clearing the MSB. There are two ways I know of to take the 2s complement:

    1. Subtract the negative number from 0
    2. Take the 1s complement and add 1
     
  4. beenthere

    Retired Moderator

    Apr 20, 2004
    15,815
    282
    I was going by the above.
     
  5. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    That is not quite right!
    Yes you can test for a negative number by looking at the MSB or for that matter just load the number into the the W register and check the N bit, but to get the absolute value of a negative number you have to take the 2's complement of the number (invert the bits and add 1).
    Another way to do it iis to multiply the negative number by -1, this is simple in the PIC18 series since they have a multiple command in their instruction set.
     
  6. Papabravo

    Expert

    Feb 24, 2006
    10,144
    1,791
    Are you saying your answer would be different if the range had been [-128,...,127] clearly suggesting 2s complement representation. If so I'll buy it...barely. LOL
     
  7. atferrari

    Thread Starter AAC Fanatic!

    Jan 6, 2004
    2,648
    764
    Thanks to all for your time.

    Had to use MPSIM to be sure (shame on me :( ) that my negative constants were expressed in (what else?) two's complement.

    Finally solved as follows:

    Code ( (Unknown Language)):
    1.  
    2. ABS_TO_TABLE  MACRO TAPS
    3.               LOCAL INDEX
    4.               LOADREG FSR2L,LOW TABLE_COEFFS
    5.               LOADREG FSR2H,HIGH TABLE_COEFFS
    6.  
    7.               INDEX=0
    8.  
    9.               WHILE INDEX<TAPS           ;INDEX =0 to TAPS-1
    10.  
    11.               IF COEFF#v(INDEX)>=0      ;positive coefficient
    12.                 MOVLW COEFF#v(INDEX)    ;absolute value already
    13.               ELSE                      ;negative coefficient
    14.                 MOVLW -(COEFF#v(INDEX)) ;we get absolute vale
    15.               ENDIF
    16.  
    17.               MOVWF POSTINC2            ;absolute value goes to table.
    18.  
    19.               INDEX=INDEX+1
    20.               ENDW
    21.  
    22.               ENDM
    23.  
     
  8. Papabravo

    Expert

    Feb 24, 2006
    10,144
    1,791
    Use any tool in the toolbox to figure out what you need.
     
Loading...