1

I have a variable defined in C on a PIC24

Let's say the name of the variable (in the C file) is The_Number_Of_Bytes

In the PIC24 C code, it is defined like this....

 unsigned long The_Number_Of_Bytes=0;   // number of bytes in buffer

I'm going to be called when an array of bytes named DATABUF01 will contain The_Number_Of_Bytes bytes (sorry for the implied redundancy) and I will need to make sure that I do that many bytes, exactly, and then stop.

I'm pretty confident that the number will be less than 65535, so why it is an unsigned long is for other discussions. For now, I want to know; which is the high order word and which is the low order word ? (For that matter, is long a 32 bit number in PIC24 C ?)

Could somebody tell me What will be in W2 and W3 in this example ?

    Mov.W   #_The_Number_Of_Bytes, W1       ;From the dispatcher
    Mov.W   [W1++], W2                      ;My question: Hi Order or Low Order ?
    Mov.W   [W1],   W3                      ;My question: Hi Order or Low ?

    Mov.W   #_DATABUF01, W4                 ;The Start

    Mov.B   [W4++], W5                      ;First byte...

    :                                       ;Whatever
    :                                       ;Whatever
    :                                       ;Whatever

Could someone please confirm or correct my thinking about Hi / Low order of the unsigned long int ?

EDIT commenter requested this. May answer the question (comments are mine)

Requested comment, The size appears to be 4 bytes, from this...

  45:                 unsigned long i=0;    
    0AB6A  B80060     mul.uu 0x0000,#0,0x0000    ;make a zero
    0AB6C  980710     mov.w 0x0000,[0x001c+2]    ;no clue which word
    0AB6E  980721     mov.w 0x0002,[0x001c+4]    ;aha, if I made it 1 or 2, I'd know
  46:                 unsigned int Fischer;
  47:                 
  48:                 Fischer = sizeof(i);
      0AB70  200040     mov.w #0x4,0x0000         ;So it must be 4
      0AB72  780F00     mov.w 0x0000,[0x001c]     ;okay, it's a 4 byte number
  49:                 
User.1
  • 2,562
  • 3
  • 33
  • 40
  • PIC is Little Endian which makes the first byte (W1, in this case, I believe) the low byte... I'm not 100% sure, though, so just doing this as a comment. – Pete Mar 19 '13 at 19:02
  • You can get the size of a long with sizeof(long). – fonZ Mar 19 '13 at 19:03
  • Does PIC24 C have a `sizeof` function? – Robert Harvey Mar 19 '13 at 19:03
  • if its C, i guess it should have, but its a guess. – fonZ Mar 19 '13 at 19:04
  • @RobertHarvey, no clue. If so, how do I use it ? – User.1 Mar 19 '13 at 19:04
  • 2
    @fonZ `sizeof` is part of the standard, so if it doesn't have `sizeof`, it's not C. – Daniel Fischer Mar 19 '13 at 19:04
  • Since most of us don't have a PIC24 C compiler, how hard would it be for you to run some simple experiments to verify the high-order and low-order bytes? – Robert Harvey Mar 19 '13 at 19:05
  • @DanielFischer okay, show me how to use it for my assembly code. Example ? – User.1 Mar 19 '13 at 19:05
  • @User.1 `printf("%zu\n", sizeof(long));`, or, if PIC24 doesn't support the `%zu` conversion, `printf("%lu\n", (unsigned long)sizeof(long));`. (That's C of course, no idea about PIC24 assembly.) – Daniel Fischer Mar 19 '13 at 19:05
  • @DanielFischer, no stdio on this; it's an embedded chip. (I think this is true) – User.1 Mar 19 '13 at 19:06
  • @User.1 in that case, perhaps `write` the number to whatever output you have (after converting it to a string)? – Daniel Fischer Mar 19 '13 at 19:08
  • Yeah, you're gonna have to figure out how to get some readable output, otherwise all hope is lost. – Robert Harvey Mar 19 '13 at 19:11
  • @DanielFischer, Hey, I can step through this in a (very good) debugger, how about this ? I have another variable, ` unsigned long i=0;` could I do this ? `unsigned int Fischer; Fischer = sizeof(i);` – User.1 Mar 19 '13 at 19:11
  • @User.1: Looks good to me. Why don't you do a little background research with your very good tools and get back to us. – Robert Harvey Mar 19 '13 at 19:13
  • Yes, that would (should, at least) work. Note that if you use a variable, you don't need parentheses, `sizeof i` suffices. – Daniel Fischer Mar 19 '13 at 19:13
  • Ha Ha, my "very good" debugger just froze. Must restart. Back to you in 10. Oh great, it more than froze. It is holding my computer hostage. Must restart entire system. Back to you in 15 – User.1 Mar 19 '13 at 19:16
  • @DanielFischer I just took your suggestion. I will next init the `i` to 1 or 2 or 257 or something, and I should have it. I hope – User.1 Mar 19 '13 at 19:52
  • Got the answer, should I post it ? – User.1 Mar 19 '13 at 20:26

2 Answers2

2

Here's a snippet from MPLAB C Compiler for PIC24 MCU's User's Guide:

5.3 DATA REPRESENTATION
Multibyte quantities are stored in “little endian” format, which means:

  • The least significant byte is stored at the lowest address
  • The least significant bit is stored at the lowest-numbered bit position

As an example, the long value of 0x12345678 is stored at address 0x100 as follows:
0x1000x1010x1020x103
 0x78  0x56  0x34  0x12 

As another example, the long value of 0x12345678 is stored in registers w4 and w5:
   w4       w5   
0x56780x1234

Mickie Byrd
  • 211
  • 3
  • 8
  • Here you go. It should be on page 79. http://ww1.microchip.com/downloads/en/DeviceDoc/51284H.pdf – Mickie Byrd Aug 25 '14 at 22:10
  • And there it is on page 79 as you suggested. Thank you Mickie ! Bonus: a page or two later, we get it documented ! "...The lower-numbered register contains the least significant 16-bits of the value..." Super find, expert detective work Mickie; Vote up and check mark – User.1 Aug 25 '14 at 23:42
1

you can also view the assembly for a program to try to get an idea of how their compiler does it... for instance:

int main(int argc, char** argv)
{
  long i = 56;
  long j = i;
  return 0;
}

becomes... ( xc16-gcc -S main.c )

    .file "/Users/grady/MPLABXProjects/testpic24.X/main.c"
    .section    .text,code
    .align  2
    .global _main   ; export
    .type   _main,@function
_main:
    .set ___PA___,1
    lnk #12
    mov w0,[w14+8]
    mov w1,[w14+10]
    mov #56,w4
    mov #0,w5
    mov.d   w4,[w14]
    mov.d   [w14],w4
    mov w4,[w14+4]
    mov w5,[w14+6]
    clr w4
    mov w4,w0
    ulnk    
    return  
    .set ___PA___,0

    .section __c30_signature, info, data
    .word 0x0001
    .word 0x0000
    .word 0x0000

; MCHP configuration words

    .set ___PA___,0
    .end
Grady Player
  • 14,399
  • 2
  • 48
  • 76