struct tag { char a:7; char b:1; }; unsigned char foo(void) { struct tag test; test.b = 1; return test.b; } void main(void) { char dat; if(foo() == 1)// ***foo return 0x80 not 0x01 { dat = 2; } while(1); }
17: void main(void) 18: { 19: char dat; 20: 21: if(foo() == 1) C:0x000F 12001A LCALL foo(C:001A) C:0x0012 BF0103 CJNE R7,#0x01,C:0018 22: { 23: dat = 2; C:0x0015 750802 MOV 0x08,#0x02 24: } C:0x0018 80FE SJMP C:0018 8: unsigned char foo(void) 9: { 10: struct tag test; 11: 12: test.b = 1; 13: C:0x001A 430980 ORL 0x09,#P0(0x80) 14: return test.b; C:0x001D E509 MOV A,0x09 C:0x001F 5480 ANL A,#P0(0x80) C:0x0021 FF MOV R7,A 15: }
... I tend to think that something isn't right here.
I thought the same as you. When I first tried it with the signed char, things were obviously wrong and I thought I understood. When I converted to unsigned char, it looked right. I then tried it later and it didn't work. Must have done something different, but don't know what. This was all determined by looking at the disassembly.
As written, the code worked for me: dat is assigned a value of 2 and its branch is executed.
however, if you change
char dat;
by giving dat a value, like
char dat=1;
the branch isn't executed.
I didn't take a look at the disassembly but I tend to think that something isn't right here.
Keil support should be interested in this. Contact them.
struct tag { unsigned char a:7; unsigned char b:1; }; unsigned char foo(void) { struct tag test; test.b = 1; return test.b; } void main(void) { unsigned char dat; if(foo() == 1)// ***foo return 0x80 not 0x01 { dat = 2; } while(1); }
17: void main(void) 18: { 19: unsigned char dat; 20: 21: if(foo() == 1)// ***foo return 0x80 not 0x01 C:0x000F 12001A LCALL foo(C:001A) C:0x0012 BF0103 CJNE R7,#0x01,C:0018 22: { 23: dat = 2; C:0x0015 750802 MOV 0x08,#0x02 24: } C:0x0018 80FE SJMP C:0018 8: unsigned char foo(void) 9: { 10: struct tag test; 11: 12: test.b = 1; 13: C:0x001A 430980 ORL 0x09,#P0(0x80) 14: return test.b; C:0x001D E509 MOV A,0x09 C:0x001F 5480 ANL A,#P0(0x80) C:0x0021 FF MOV R7,A 15: }
THE RESULT IS THE SAME!
What is the sign-ness of char for your build?
Assuming a char is signed then:
You have an element with a width of 1 bit as a signed char. Does a 1 bit twos complement value make any sense?
When you return the value it is being converted to an unsigned char. What conversion will occur?
Likely that you intended your 1 bit variable to be unsigned. Try it.