Jump to content

Getting/setting Bytes Of A Long

Recommended Posts



I was wondering if there was an easy (short-hand) way to read/write the individual bytes of a long?

(I tried things like long_value.0, or long_value[0], but they didn't work).


I wrote these functions, but was hoping there was something more efficient:


#define get_byte_3_of_long(long_byte_3, long_value) \
_asm movf _long_value+3, W \
_asm movwf _long_byte_3
#define get_byte_2_of_long(long_byte_2, long_value) \
_asm movf _long_value+2, W \
_asm movwf _long_byte_2
#define get_byte_1_of_long(long_byte_1, long_value) \
_asm movf _long_value+1, W \
_asm movwf _long_byte_1
#define get_byte_0_of_long(long_byte_0, long_value) \
_asm movf _long_value, W \
_asm movwf _long_byte_0
#define set_byte_3_of_long(long_byte_3, long_value) \
_asm movf _long_byte_3, W \
_asm movwf _long_value+3
#define set_byte_2_of_long(long_byte_2, long_value) \
_asm movf _long_byte_2, W \
_asm movwf _long_value+2
#define set_byte_1_of_long(long_byte_1, long_value) \
_asm movf _long_byte_1, W \
_asm movwf _long_value+1
#define set_byte_0_of_long(long_byte_0, long_value) \
_asm movf _long_byte_0, W \
_asm movwf _long_value




Link to comment
Share on other sites



My usual approach is to use a pointer to byte (unsigned char) pointing to the long, and use it to index the bytes of the long.

In the code bellow you can see this approach applied with the help of macros.

In this sample the byte offset is hardcoded in the macros but you can rewrite them to accept it as a parameter.

#include <system.h>

typedef unsigned char BYTE;

// Access bytes of a long
#define    LongByte0(LONGVAR)    (((BYTE*)&LONGVAR)[0])
#define    LongByte1(LONGVAR)    (((BYTE*)&LONGVAR)[1])
#define    LongByte2(LONGVAR)    (((BYTE*)&LONGVAR)[2])
#define    LongByte3(LONGVAR)    (((BYTE*)&LONGVAR)[3])

// declare evrything volatile to prevent it beeing optimized out
// so the code can be tested in the Simulator
volatile long long_value;
volatile long long_reverse_value;

volatile BYTE b0;
volatile BYTE b1;
volatile BYTE b2;
volatile BYTE b3;
void main(void)
    long_value = 0x12345678;

    // Extract bytes from a long
    b0 = LongByte0(long_value);
    b1 = LongByte1(long_value);
    b2 = LongByte2(long_value);
    b3 = LongByte3(long_value);    

    // Insert the bytes on another long in reverse order

}  //void main(void)

Best regards


Edited by JorgeF
Link to comment
Share on other sites

How about this:




#define get_byte_3_of_long(long_value)  ((unsigned char)(long_value >> 24))
#define get_byte_2_of_long(long_value)  ((unsigned char)(long_value >> 16))
#define get_byte_1_of_long(long_value)  ((unsigned char)(long_value >> 8))
#define get_byte_0_of_long(long_value)  ((unsigned char)(long_value))

long mylong = 0x12345678;
unsigned char byte0 1 = get_byte_1_of_long( mylong );




Link to comment
Share on other sites

How about a union?:

	unsigned long ulong;
	unsigned char byte[4];
mylong.ulong = 0x12345678;
unsigned char byte0 = mylong.byte[0];
unsigned char byte1 = mylong.byte[1];
unsigned char byte2 = mylong.byte[2];
unsigned char byte3 = mylong.byte[3];


Not tested!






Link to comment
Share on other sites

#define SECTOR_FETCH16(Index) (*(unsigned short *)&SectorBuf[index])
#define SECTOR_FETCH32(Index) (*(unsigned long *)&SectorBuf[index])
#define BUF_FETCH32(Buffer) (*(unsigned long *)Buffer)
//(SectorBuf[Offset+3]<<24) | (SectorBuf[Offset+2]<<16) | (SectorBuf[Offset+1]<<8) | SectorBuf[Offset+0])
//(SectorBuf[Offset+1]<<8) | SectorBuf[Offset+0])


I used the macros above as they resulted in less code on an 18F part than the shifting method in the comments. I would think that JorgeF's technique would result in less/faster code than the shifting. I also used the union technique in another situation so it would be worth doing the experiment to see which of the three tricks generate the best code.

Link to comment
Share on other sites

  • 2 weeks later...

As awkward as it might be to implement, could something like this be useful?

        unsigned long test32 @0x20 = 0x12345678;
        unsigned char testlo @0x20;
        unsigned char testhi @0x21;
        unsigned char testul @0x22;
        unsigned char testuh @0x23;


       row = testlo;
003C  5020       MOVF gbl_testlo, W
003E  6E01       MOVWF gbl_row
       col = testhi;
0040  5021       MOVF gbl_testhi, W
0042  6E02       MOVWF gbl_col
Edited by Mike McLaren
Link to comment
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...