This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.
See the CrossGCC FAQ for lots more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On Tue, Feb 08, 2005 at 09:54:31PM +0100, Thomas Kolejka wrote: > Hello, > > I'm working on an Arm processor and tried to make the following program run: > > > typedef unsigned char U1; > typedef U1 * P_U1; > > > U1 data[100]; > > int main() > { > int i; > > U1 *p = 0x87654321; > > P_U1 *p2; > > printf("p: -> %p\n", (void *)p); > > for (i = 0; i < 10; i++) > { > p2 = (P_U1)&data[i]; > // ldr r2, .L10+4 > // ldr r3, [fp, #-16] @ i > // add r3, r2, r3 > // str r3, [fp, #-24] @ p2 > > > printf("p2: -> %p\n", (void *)p2); > > *p2 = p; > // ldr r2, [fp, #-24] @ p2 > // ldr r3, [fp, #-20] @ p > // str r3, [r2, #0] > } > > for (i=0; i < 10; i++) > printf("0x%0x ", data[i]); > > printf("\n"); > } > > > > The program should write 0x87654321 into every position of data[100] - > therefore overwrite 3 bytes > of the last write. > On the PC (Pentium III) this works alright; on the ARM only every fourth > value > is written to the memory: "str r3, [r2, #0]" is executed (gdb, ddd: ni), but > nothing happens. > > Including 'asm("str r3, [r2]");' into the code does not work, too. > > I've tested a lot of options for gcc and arm-options, but nothing changed. > > This happens with gcc version 2.95.3 and 3.3.2. > > > Thanks in advance for any help, > > Thomas It looks like you're doing unaligned word writes with the line *p2 = p; Some ARM cores, depending on the specific architecture, don't take kindly to writing 32-bit quantities on non-0-mod-4 addresses. Some will silently accept the instruction and do the wrong thing, without throwing any kind of processor exception. In particular, I've personally observed ARM cores do the following... assume little endian, intial memory condition: 0x0000: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 now you execute *(unsigned long*)3 = 0x12345678; you'd expect to get: 0x0000: 0x00 0x00 0x00 0x78 0x56 0x34 0x12 0x00 but instead you get: 0x0000: 0x56 0x34 0x12 0x78 0x00 0x00 0x00 0x00 the general pattern being that for every byte written that's in a different word than the address given in the store instruction (e.g. 3 in this case, so 3 is in the same word; 4, 5, 6 are in a different word), byte n-4 gets written with what byte n should have gotten, thus all bytes modified are in a single word. The byte lane switching portion of the unaligned access works, but there's only a single word access made to memory, as the core can't split a word write across two word accesses to memory. So everything ends up in the first word of the two that were meant to be spanned. Did that make sense? Bottom line is, unaligned word writes are not guaranteed to work in general. Some machines happily take them; some machines throw an exception; some machines just plain do the wrong thing with them. It's architecture- dependent. The compiler makes it somewhat difficult to generate an unaligned word write because it's not supported. If you force the compiler to generate one, then you're taking your chances with your target architecture, and if it doesn't do what you had hoped, it's not the compiler's fault. You mention it works in a PC. Under what OS? Windows generally allows it. Linux generally gives an exception. This is because the x86 architecture does support unaligned word accesses, but it also has a bit in one of the machine configuration registers to disallow them and give a processor exception. Windows runs with that bit off. Linux runs with it on. If it's Windows you've been trying it under, give the exact same code a shot under Linux. I bet it cores with a SIGBUS. ------Carl ------ Want more information? See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/ Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |