3 ms·
I forget the details (long time ago) but char* and int* pointers had a different internal structure. The assembly generated by the compiler when code accessed a
by billpg 4y ago
I forget the details (long time ago) but char* and int* pointers had a different internal structure. The assembly generated by the compiler when code accessed a char* pointer was optimized for accessing single bytes and was very different to the code generated for an int* pointer.
Digging deeper, this particular microcontroller was tuned for accessing 32 bits at a time. Accessing individual bytes needed extra bit-shuffling code to be added by the compiler.
- leeter 4y agoSounds like M68K or something similar, although Alpha AXP had similar byte level access issues. A compiler on either of those platforms likely would add a lot of fix up code to deal with the fact they have to load the aligned (either 16bit in M68K case or 32Bit IIRC in Alpha) and then do bitwise and shifts depending on the pointers lower bits. Raymond's blog on the Alpha https://devblogs.microsoft.com/oldnewthing/20170816-00/?p=96825 https://devblogs.microsoft.com/oldnewthing/20170816-00/?p=96...
- monocasa 4y agoM68k was byte addressable just fine. Early alpha had that issue though, as did later cray compilers. Alpha fixed it with BWX (byte word extension). Early cray compilers simply defined char as being 64bits, but later added support for the shift/mask/thick pointer scheme to pack 8 chars in a word.
- leeter 4y agoMust have depended on variant, the one we used in college would throw a GP fault for misaligned access. It literally didn't have an A0 line. That said it's been over 10 years and I could be remembering the very hard instruction alignment rules as applying to data too...
- monocasa 4y ago16bits had to be aligned. It didn't have an A0 because of the 16bit pathway, but it did have byte select lines (#UDS, #LDS) for when you'd move.b d0,ADDR so that devices external to the CPU could see an 8-bit data access if that's what you were doing.
- wyldfire 4y ago> char* and int* pointers had a different internal structure. The assembly generated by the compiler when code accessed a char* pointer was optimized for accessing single bytes and was very different to the code generated for an int* pointer. But -- they are different. Architectures where they're treated the same are probably the exception. Depending on what you mean by "very different" - most architectures will emit different code for byte access versus word access.
- billpg 4y agoAccessing a 32 bit word was a simple read op. Accessing an 8 bit byte from a pointer, the compiler would insert assembly code into the generated object code. The "normal" part of the pointer would be read, loading four characters into a 32 bit register. Two extra bits were squirreled away somewhere in the pointer and these would feed into a shift instruction so the requested byte would appear in the lowest-significant 8 bits of the register. Finally, an AND instruction would clear the top 24 bits.