Please help

Programming, for all ages and all languages.
Post Reply
NOTNULL

Please help

Post by NOTNULL »

Hi all,
I have 2 binary files in my embedded system. One file is compiled with 16-bit code alignment and the other with 32-bit code alignment. I have a structure declared in the 16 bit code. I pass the address of the structure to a function in the 32 bit code and assign a value in the structure member (int). When I print the value after assigning the variable in the same function, it is found to be correct. But, when I print the value after returning from the function in the 16 bit code, the value seems to be incorrect. For example, if I assign 0x23 in the 32 bit code, i get 0x2300 in the 16 bit code. Why does this happen? The processor is Motorola 68020. Compiler mcc68k, Assembler asm68k, Linker lnk68k. When both the code were 16 bit aligned, there was no problem. But, I face this problem only after converting a binary to 32 bit code.

And, another question, what should be the size of a pointer in the 16 bit code? Shouldn't be 2 bytes? But, I get 4 bytes as the size of the integer both in 16 bit and 32 bit code. I am totally confused. Please, help me out of this problem.

Any help greatly appreciated.
Thanks.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Please help

Post by distantvoices »

you need to ask for

Code: Select all

sizeof(* int)
then you'll get the size of a pointer in your development environment (your gcc especially).
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Please help

Post by Candy »

that would be

Code: Select all

sizeof(int *);
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Please help

Post by Pype.Clicker »

NOTNULL wrote: But, when I print the value after returning from the function in the 16 bit code, the value seems to be incorrect. For example, if I assign 0x23 in the 32 bit code, i get 0x2300 in the 16 bit code. Why does this happen?
You should be *extremely* careful when passing data (and esp. structures) among dissimilar architectures (which is basically what you have here). things like "int" or "short" will have a compiler-dependent width (e.g. int is 2 bytes in one and 4 bytes in the other). That mean if i have

Code: Select all

struct point {
   int x,y;
};
and write 32bits code that fills x=1234 and y=5678, the resulting bytes could be [tt]0000123400005678[/tt] while the 16 bits code expects to have [tt]xxxxyyyy[/tt].

The solution might be to use fixed-size types only (e.g. uint32_t or uint16_t depending on what you have) and rely on the compiler's header files to translate that into "unsigned int" for 32 bits and "unsigned long" for 16 bits system.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Please help

Post by distantvoices »

@candy: thanks for correction, have mixed it up :-)
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Schol-R-LEA

Re:Please help

Post by Schol-R-LEA »

The actual problem is that you are using 16-bit data alignment, but it is still 32-bit data once it is read in - the 68K series doesn't have a 16-bit mode the way that the x86 series does.

The confusion comes from the fact that the 68000 and the 68010 had a 16-bit data path, which forced it to fetch twice for every data reference. To save wait cycles and memory space, it allowed programmers to fetch 16 bit values, hence the support for 16-bit alignment. However, the data registers were actually 32 bit regardless of the data size used, and it did not have anything equivalent to the 'high' and 'low' bytes of the x86 registers - all register accesses were for the full 32 bit value. Also, those two models used only 24 address lines, even though the address registers were also all 32 bits wide.

The 68020, however, has a full 32 bit address space, and pointers are always 32 bits on it. It still allowed 16-bit data alignment and data access for backwards compatibility, but it gained nothing in terms of speed and was hence deprecated for future use.

This is all from my admittedly faulty memory; comments and corrections are welcome.

Why did you happen to use 16 bit data alignments, and why do you need to convert them? What are the source of the files in question, and how are they stored (particularly relevant if this is an embedded system as you say). The purposes may be relevant to your problem, and may allow a way to avoid it entirely.
Post Reply