| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| bennyboos 
 
 
 Joined: 17 Nov 2005
 Posts: 30
 Location: Chester UK
 
 
			    
 
 | 
			
				| Inverse of make8() |  
				|  Posted: Thu Sep 24, 2020 11:20 am |   |  
				| 
 |  
				| 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
  |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9588
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Sep 24, 2020 11:34 am |   |  
				| 
 |  
				| 'union'..... search for it, last week or 2 ago....,simlar request...
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Sep 24, 2020 12:38 pm |   |  
				| 
 |  
				| <http://www.ccsinfo.com/forum/viewtopic.php?t=58956> |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9588
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Sep 25, 2020 8:59 am |   |  
				| 
 |  
				| 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: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Sep 25, 2020 11:15 am |   |  
				| 
 |  
				| Yes.   I use it a lot.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |