> Isn't it the preprocessor that tries to evaluate '0 - var'? No, that is evaluated by the assembler proper.=20 Please take the time to carefully read and understand the following. It wil= l probably solve your problem. Perhaps more importantly, if you study it closely, you will have a much better handle on how the assembler and linker interact. If var were at a known address at assembly time (say in an absolute section= ) then you might think it would work because the assembler could resolve the expression itself without involving the liker. Unfortunately that is not th= e case. Assume 'var' is in a absolutely addressed section like this: myseg udata H'20' var res 1 You would think the assembler should be able to determine that low(0-var) was simply H'E0'. However, even this won't work. The assembler does not 'know' in its symbol table that 'var' is in an absolutely addressed section and thus has an address that could be known at assembly time. The only way that I can think of to make this work would require a trick like this: work_abs equ H'30' work udata work_abs work_base: adummy res 3 var_abs =3D ($-work_base)+work_abs var res 1 mycode CODE movlw low (0-var_abs) This, no doubt, needs some explanation. Let's take it one line at a time... [1] work_abs equ H'30' This is creating an assembly time symbol containing the absolute value H'30'. This is where we plan on placing our variables.=20 [2] work udata work_abs This is declaring a data section, and tells the linker exactly where it has to appear in memory. Now the linker and the assembler agree on where the data will go. It is critical to understand that for this to work our sectio= n must be located at a location known at assembly time (ie: at 'work_abs'). [3] work_base: This is declaring another symbol to the assembler. This one is a relocatabl= e symbol with the value "0 in the 'work' section".=20 [4] adummy res 3 This line is here just to show that other variables can be declared as normal in the 'work' section. [5] var_abs =3D ($-work_base)+work_abs This line contains the 'magic' that makes this whole scheme work. We'll tak= e it apart to understand what it is doing: The dollar sign is a pseudo symbol for the current offset in the current section. Thus at this point it has the value "3 in the 'work' section". Work base, as described above is also a symbol with the value "0 in the 'work' section". Thus, $-work base is computed by the assembler as just plain 3, because the "in the 'work' section" parts of the two symbols cancel in the subtraction.= =20 Next we add in work_abs, which you will remember is the absolute value H'30'. This gives us the absolute value H'33', which of course is where the linker is going to end up putting 'var'. [6] var res 1 Allocates the 'var' inside the 'work' section. It is important to note that 'var' is now a symbol with the relocatable value "3 in the 'work' section". [7] mycode CODE Just moving to the code section so we can put in instructions. [8] movlw low (0-var_abs) The argument to 'low' is the difference of two _absolute_ expressions. The result, of course, is also absolute, and so the assembler is happy with it. -- Bob Ammerman RAm Systems -----Original Message----- From: piclist-bounces@mit.edu [mailto:piclist-bounces@mit.edu] On Behalf Of Ruben J=F6nsson Sent: Thursday, October 03, 2013 7:58 AM To: Microcontroller discussion list - Public. Subject: Re: [PIC] Load the address of a variable as 2's complement? Hmm, not sure I understand why my comment is wrong then? Isn't it the preprocessor that tries to evaluate '0 - var'? /Ruben > No, this isn't a preprocessor issue. The preprocessor doesn't 'know'=20 > the address of anything. It just manipulates text. >=20 > -- Bob Ammerman > RAm Systems >=20 > -----Original Message----- > From: piclist-bounces@mit.edu [mailto:piclist-bounces@mit.edu] On=20 > Behalf Of Ruben J=F6nsson > Sent: Thursday, October 03, 2013 7:14 AM > To: Microcontroller discussion list - Public. > Subject: Re: [PIC] Load the address of a variable as 2's complement? >=20 >=20 > > Hello, > >=20 > > Some time ago I wrote an Insertion sort algorithm for Mid-range PICs=20 > > and today decided to optimize it as much as possible. For this I=20 > > need to load the negative value of an address of a variable. Using=20 > > 'movlw 0 - var' or 'addlw 0 - var', where var is a file register is=20 > > not accepted by MPASM, and 'Error[151] : Operand contains=20 > > unresolvable labels or is too complex' is issued. > >=20 > > Currently I found 2 workarounds - one needs an extra instruction to=20 > > convert the loaded address to a negative number, and the other=20 > > defines an absolute address of 'var' in RAM and then a precalculated=20 > > negative value of that address is used in the code. > >=20 > > Both of these do not seem right, so I'm searching for a trick to=20 > > negate the address of 'var' in the preprocessor, without triggering=20 > > an > error. > >=20 >=20 > The preprocessor doesn't know the address of var. >=20 > /Ruben >=20 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Ruben J=F6nsson AB Liros Electronic Box 9124 200 39 Malm=F6 Sweden www.liros.se Tel +46 40142078 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -- http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/chang= e your membership options at http://mailman.mit.edu/mailman/listinfo/piclist --=20 http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .