Search code examples
assemblymplabpic18

PIC 18F8722 variable declaration adresses


I know I can declare a variable in that way.

variable   udata 0x20

But what is the memory limit for this? Is

variable   udata 0x35 

a valid instruction? I mean, can I use address 0x35? Is it spared to me, not SFRs? Also, how can calculate space of such addresses since I need to use a lot flags which I will implement using such variables?

Thanks in advance.


Solution

  • Well, first of all you need to know the difference between instructions and compiler/assembler directives. udata is actually an assembler directive, which means it isn't executable nor placed in the program memory. Its logic is evaluated before the program is even compiled into the machine code.

    The example you provided in your question is not a proper way of declaring a variable - you're just naming a specific address in memory and telling the assembler that it's not going to be initialized.

    udata declares a start of an unitialized data section. You can name it, that's true, but far better practice is to use it just as a grouping tool, like here:

    uninitializedGroup udata 0x20
     myVariable1 res 1
     myVariable2 res 1
    
    initializedGroup idata
     dead dw 0xbeef
     visit dw 0xcafe
    

    res here is the directive used for the allocation, advancing the memory pointer by 1 and therefore reserving a byte for myVariable1.

    Note that you don't even have to specify the memory location for your data - if you leave the rest of the line after udata/idata directive blank, linker will automatically find memory for your variables (avoiding conflicts with system registers) or inform you if there isn't any space left.

    TL;DR:

    • Specify or allocate addresses for your data using udata and idata for uninitialized and initialized data in your program, respectively. Place a label at the beginning of the line if you need to access the memory locations they represent.

    • Reserve memory for your variables in these memory locations by res number-of-bytes.

    • If you ever come to a situation that you have to access a larger pack of variables without always switching the banks, use udata_acs and idata_acs which will place them into the Access Memory.

    Speaking in general, you can always check the address ranges for chip´s registers in the datasheet.

    Speaking just for your specific case, PIC18F8722 family doesn't have much trouble with memory banks. Memory range above 0x20 and under 0x960, and the range above 0x1000 should be yours to use.