1
\$\begingroup\$

Within an XC16 assembly code portion, I want to use a C variable as a literal. Here's a portion of my code :

C function :

int x=4; int *TrisCSX = (int*) 0x2C8; 

x and *TrixCSX are declared as global variables.

Assembly code :

.global _x .global _TrisCSX bclr _*TrisCSX, _x 

This leads to an error : "Error: Invalid operands specified. Check operand #0".

If I change _x by #1, the error disappears.

I had this error before when I omitted the "#" before the literal expression when writing it as a number, but writing #_x doesn't work.

Processor used is PIC24FV32KA302.

Any idea?

\$\endgroup\$
4
  • \$\begingroup\$ I'm not looking at the syntax much. But, memory serving, at least some of the target processors for XC16 cannot move from one memory location to another in a single instruction. This may explain why #1 works but an instance in memory doesn't. Perhaps you might share the target processor with us. \$\endgroup\$ Commented Jul 26 at 10:06
  • \$\begingroup\$ @periblepsis The MCLR opcode for 16-bit PICs includes 4 bits of data for which bit (0..15) you want to clear and 12 bits of data for which register file address you want to access. They need to be literals to select one of the 65536 BCLR (in f) opcodes. \$\endgroup\$ Commented Jul 26 at 10:33
  • \$\begingroup\$ Do you actually need that value to be in a variable (I.e. it’s value may change on execution)? Or can you switch it to a constant e.g. #define X 4? \$\endgroup\$ Commented Jul 26 at 15:04
  • \$\begingroup\$ Yes, as this assembly code is dedicated to a library I want to be able to configure from the main program which uses it. \$\endgroup\$ Commented Jul 27 at 8:00

1 Answer 1

4
\$\begingroup\$

Variables that are located in some memory address and contain some value in that memory address are not literals so what you want to do is impossible, you cannot use variables as literals in assembly code.

The BCLR opcode itself contains the number of bit which shall be affected.

It basically means you need to find another way than BCLR if you want to clear a bit which resides in a variable. It likely consists of multiple opcodes where you need to load/move the memory address of the variable to some register if needed, load the value of the variable from that memory address to a register. If you don't have an opcode to clear a bit number that resides in a registers, you need convert the bit number to bit mask by shifting, and if you have no opcode to clear bits that are set then you need to invert the mask, and then AND the mask with the register you want. Before that you need to load the TRIS register contents to some other register so you can AND it with the mask and then you can write it back to TRIS register.

\$\endgroup\$
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.