CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Inverse of make8()

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bennyboos



Joined: 17 Nov 2005
Posts: 30
Location: Chester UK

View user's profile Send private message

Inverse of make8()
PostPosted: Thu Sep 24, 2020 11:20 am     Reply with quote

So, I wanted an efficient means of accessing a byte (low or high) of a larger data type such as a word
I know make8() gives me a means to extract a byte, but what if I want to put one or other byte back into a word ?

I tried using the following macro from my old HiTech C days, however under CCS (latest version) each line produces 6 lines of assembly, involving the FSR ?
Seems overly complicated to me - when it ought to just a few lines of assembly at most
Code:
// Demo of clumsy access to bytes within a word
#include <18F8723.h>

// The following #defines provide easy access to the
// individual bytes of multibyte variables
#define byte0(var)   *((unsigned int8 *)&var + 0)
#define byte1(var)   *((unsigned int8 *)&var + 1)
#define byte2(var)   *((unsigned int8 *)&var + 2)
#define byte3(var)   *((unsigned int8 *)&var + 3)

unsigned int16   data[1];
void main(void)
{
   byte0(data[0]) = 0x43;
   byte1(data[0]) = 0x21;
}

And here is the disassembly of it
Code:

1:                 // Demo of clumsy access to bytes within a word
 00000    EF02     GOTO 0x4
2:                 #include <18F8723.h>
3:                 
4:                 // The following #defines provide easy access to the
5:                 // individual bytes of multibyte variables
6:                 #define byte0(var)   *((unsigned int8 *)&var + 0)
7:                 #define byte1(var)   *((unsigned int8 *)&var + 1)
8:                 #define byte2(var)   *((unsigned int8 *)&var + 2)
9:                 #define byte3(var)   *((unsigned int8 *)&var + 3)
10:               
11:                unsigned int16   data[1];//   #locate dataArray=0x100
12:                void main(void)
 00004    6AF8     CLRF 0xff8, ACCESS
 00006    9ED0     BCF 0xfd0, 0x7, ACCESS
 00008    50C1     MOVF 0xfc1, W, ACCESS
 0000A    0BC0     ANDLW 0xc0
 0000C    090F     IORLW 0xf
 0000E    6EC1     MOVWF 0xfc1, ACCESS
 00010    0E07     MOVLW 0x7
 00012    6EB4     MOVWF 0xfb4, ACCESS
13:                {
14:                   byte0(data[0]) = 0x43;
 00014    6A28     CLRF 0x28, ACCESS
 00016    0E00     MOVLW 0
 00018    6EE9     MOVWF 0xfe9, ACCESS
 0001A    C028     MOVFF 0x28, 0xfea
 0001E    0E43     MOVLW 0x43
 00020    6EEF     MOVWF 0xfef, ACCESS
15:                   byte1(data[0]) = 0x21;
 00022    6A28     CLRF 0x28, ACCESS
 00024    0E01     MOVLW 0x1
 00026    6EE9     MOVWF 0xfe9, ACCESS
 00028    C028     MOVFF 0x28, 0xfea
 0002C    0E21     MOVLW 0x21
 0002E    6EEF     MOVWF 0xfef, ACCESS
16:                }
 00030    0003     SLEEP

I realise I could use things like #byte or #locate etc, or do cunning things with unions and structs but I don't get why the compiler is over-complicating this.
Can anyone explain why and maybe help me find a simpler more efficient macro (or maybe there is some existing function I am just ignorant of?).

Thanks in advance Very Happy
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Sep 24, 2020 11:34 am     Reply with quote

'union'.....
search for it, last week or 2 ago....,simlar request...
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Thu Sep 24, 2020 12:38 pm     Reply with quote

<http://www.ccsinfo.com/forum/viewtopic.php?t=58956>
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Sep 25, 2020 8:59 am     Reply with quote

OK, I got curious while 2nd pot of coffee was brewing....

Code:
286:               union {
287:                  unsigned int32 whole;
288:                  unsigned int8 bytes[4];
289:               } combiner;
290:               
291:               combiner.whole=1599684516; //which in HEX = 5F59 3FA4
  0AA8    0E5F     MOVLW 0x5f
  0AAA    0100     MOVLB 0
  0AAC    6FF5     MOVWF 0xf5, BANKED
  0AAE    0E59     MOVLW 0x59
  0AB0    6FF4     MOVWF 0xf4, BANKED
  0AB2    0E3F     MOVLW 0x3f
  0AB4    6FF3     MOVWF 0xf3, BANKED
  0AB6    0EA4     MOVLW 0xa4
  0AB8    6FF2     MOVWF 0xf2, BANKED
292:               
293:               //then combiner.bytes[0] will contain 0xA4
294:               //combiner.bytes[1] will contain 0x3F
295:               //combiner.bytes[2] will contain 0x59, and
296:               //combiner.bytes[3] will contain 0x5F
297:               
298:               //The great thing about this is it'll work both ways. You can write (say)
299:               combiner.bytes[2]=0x1A;
  0ABA    0E1A     MOVLW 0x1a
  0ABC    6FF4     MOVWF 0xf4, BANKED
300:               
301:               //and then combiner.whole will contain 0x5F1A3FA4 = 1595555748
302:               
3


..it sure makes nice, tight code !!!

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri Sep 25, 2020 11:15 am     Reply with quote

Yes. Smile
I use it a lot.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group