If I understand correctly, the DCPU-16 specification for 0x10c describes a 16-bit address space where each offset addresses a 16-bit word, instead of a byte as in most other memory architectures. This has some curious consequences, e.g. I imagine that sizeof(char)
and sizeof(short)
would both return 1
.
Is it feasible to keep C code portable between such different memory addressing schemes? What would be the gotchas to keep in mind?
edit: perhaps I should have given a more specific example. Let's say you have some networking code that deals with byte streams. Do you throw away half of your memory by putting only one byte at each address so that the code can stay the same, or do you generalize everything with bitshifts to deal with N bytes per offset?
edit2: The answers seem to focus on the issue of data type sizes, which wasn't the point - I shouldn't even have mentioned it. The question is about how to cope with losing the ability to address any byte in memory with a pointer. Is it reasonable to expect code to be agnostic about this?
When you say, 'losing the ability to address a byte', I assume you mean 'bit-octet', rather than 'char'. Portable code should only assume
CHAR_BIT >= 8
. In practice, architectures that don't have byte addressing often defineCHAR_BIT == 8
, and let the compiler generate instructions for accessing the byte.I actually disagree with the answers suggesting:
CHAR_BIT == 16
as a good choice. I'd prefer:CHAR_BIT == 8
, withsizeof(short) == 2
. The compiler can handle the shifting / masking, just as it does for many RISC architectures, for byte access in this case.I imagine Notch will revise and clarify the DCPU-16 spec further; there are already requests for an interrupt mechanism, and further instructions. It's an aesthetic backdrop for a game, so I doubt there will be an official ABI spec any time soon. That said, someone will be working on it!
Edit:
Consider an array of
char
in C. The compiler packs 2 bytes in each native 16-bitword
of DCPU memory. So if we access, say, the 10th element (index9
), fetch the word # [9 / 2] = 4, and extract the byte # [9 % 2] = 1.Let 'X' be the start address of the array, and 'I' be the index:
The register
A
holds the 'byte' - it's a 16 bit register, so the top half can be ignored. Alternatively, the top half can be zeroed:This is not optimized, but it conveys the idea.