We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have one question about accessing high byte of 2-byte idata variable.
Case 1: for xdata variable we can use below to access the higher byte:
#define ADDR *((_2BYTE xdata *) 0x0800) #define ADDRH *((_1BYTE xdata *) 0x0800) #define ADDRL *((_1BYTE xdata *) 0x0801)
If ADDRH is enough to make decision then we can just use ADDRH, instead of ADDR(2-byte)... This save code space...
Case 2: if ADDR is declared as "idata" then is there any way achieving the same goal like Case 1 ?
All we want to do is "save code base"...
Thanks in advance...
"If ADDRH is enough to make decision then we can just use ADDRH, instead of ADDR(2-byte)... This save code space."
The compiler is perfectly capable of doing that kind of optimisation itself - trying to micro-manage it manually at the source level like this is likely to be counter-productive.
If you really need to be looking at this kind of fine detail, then you really should be writing in assembler!
"All we want to do is 'save code base' (sic)"
Then use a union...
charvar = (shortvar << 8) generates no shifts
Erik
IS that always the case, or does it depend on optimisation level?
Is what i know.
However since it shows in the assembler from the compiler and Keil for some reason does what could be compilation optimization in the linker I guess it is even so at opt = 0.
Is below declaration/define is correct ?
_2BYTE ADDR _at_ 0x1C; // located in DATA area #define ADDRH *((_1BYTE idata *) ADDR)
If above is OK then now I can use the following code to cehck if ADDR is valid or not...
if(ADDRH=0xFF) {...}
*Original way to check is:
if(ADDR=0xFFFF) {...} // there are much this kind of code in current firmware...
Anyway,I want to use 1-byte for checking(enough), instead of 2-byte ! And want to know if this declaration/define is correct...
So just use a 1-byte variable, then!
Also, if it's a simple binary decision (ie, yes/no, true/false, etc), why not take advantage of C51's support for single-bit variables...?
And why do you want to manually fix it to an absolute address?
Back to C school. What happens if you do a "compare" using just a single equal character instead of two?
You should also not be defining names with leading underscores - these should be reserved for use by the tools!
I think I have to explain what I am doing in more detail for your reference...
1. the reason why "ADDR" is at fix location in DATA area is: our project utilizes ROM+RAM for firmware and the ROM part can not be changed once tape-out...If DATA variables are not fixed then in the future when we add new routine/feature the DATA area "arrangement" maybe changed. This causes mismatch between ROM and RAM...
2. the reason why we use one-byte for checking is: in our case ADDR(2byte) is assigned value by H/W. The original code for "checking ADDR is valid or not" is:
if(ADDR = 0xFFFF) {...}
But H/W engineer told me if H/W did not find valid address then high-byte of returned value is always "0xFF"...
Thus I think maybe below code segments can save code space:
if(ADDRH = 0xFF) {...}
p.s this kind of checks occurs much in code and thus I guess using one-byte can save more code space...
3. "... names with leading underscores..." -> I guess it means "_1BYTE", right ?
We "typedef unsigned char _1BYTE"...
The standard reserves the right to use symbols starting with a leading underscore. So obviously, you should think twice about using such symbols on your own - unless you are the maintainer of the standard.
Your second post still contains = (assign) instead of == (equals). Don't you recognize the difference.
Try this:
if (a = 5) { ... }
Now try this:
if (5 = a) { ... }
a equals b implies b equals a. But the above code will fail because it isn't a test for equals.
Another thing. Your hw engineer says that if a failure, then the high byte is always 0xff. That is an implication, not an equivalence. To be an equivalence, the reversed condition must also be true, i.e. that the high byte is never 0xff unless there is an error.
0xff00 or 0xff73 may be valid values, while 0xffff is the error value.
First so sorry for making a big mistake "in the post" We really use "==", instead of "="...!
Second, thanks for your opinion about the "equivalence". After checking with H/W engineer we think the reverse condition is also true because H/W behavior is:
if H/W found valid address then return value within [0,400] else return 0xFFFF
Thus by above if failure then high-byte = 0xFF. And if high-byte is not 0xFF then high-byte might be: 00- Ex. 0x0000~0x00FF 01- Ex. 0x0100~0x0190 These are valid/OK cases...
F.Y.I
In that case, you can reduce the code size by just performing an 8-bit test instead of a 16-bit test. An 8-bit processor doing a 16-bit test normally means that the code first checks one byte (high or low depending on compiler choice) and then decides if it needs to test the other byte - but the code is always generated for supporting testing of two bytes.
Your knowledge that the high byte is 0xff when and only when there is an error condition means that you know that there is never a need to check the low byte, and hence no need to generate any code for any such test.
Note that on a 16-bit or 32-bit processor, it may not change the code size or execution speed if you perform a one-byte test or a 16-bit test. It is only for processors that must perform a 16-bit test as two separate 8-bit comparisons - or that must load the 16-bit reference value as two 8-bit reads - that you may be reasonably sure you can get a gain from modifying the code to just look at the high byte.
1. the reason why "ADDR" is at fix location in DATA area is: our project utilizes ROM+RAM for firmware and the ROM part can not be changed once tape-out...
There's a flaw in that line of reasoning. You're fighting the tools instead of cooperating with them.
If DATA variables are not fixed then in the future when we add new routine/feature the DATA area "arrangement" maybe changed. This causes mismatch between ROM and RAM...
That would only happen if you went about that job in the wrong way. If you plan on fixing that ROM image and add to it, you should have two separate projects: one for the ROM alone, the other for the RAM alone. The RAM project should then be linked to the finished ROM image file (either the entire thing, or only its symbols).