|
|
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: 9243 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: 19539
|
|
Posted: Thu Sep 24, 2020 12:38 pm |
|
|
<http://www.ccsinfo.com/forum/viewtopic.php?t=58956> |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 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: 19539
|
|
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
|