43

I'm writing a userspace filesystem driver on Windows and endianness conversions are something I've been dealing with, as this particular filesystem always stores values in little-endian format and the driver is expected to convert them (if necessary) for the CPU it's running on. However, I find myself wondering if I even need to worry about endianness conversions, since as far as I can tell, desktop Windows only supports little-endian architectures (IA32, x86-84, etc.), and therefore, the on-disk little-endian values are perfectly fine sans conversion. Is this observation accurate, and if so, is it generally acceptable to make the assumption that Windows will always be running on little-endian hardware? Additionally, is it even possible (in 2011) to run Windows on a big-endian emulator or something, such that one could even test for endianness issues?

Edit: For additional clarity, the way my code currently works, I do an endianness check at startup time, and then every time I load a value off the disk, I run it through an inline function that uses an intrinsic to change endianness if the architecture is big-endian. The problem is, I don't know if I might have missed one or more of those places where I needed to do a conversion and the easiest way to see if I screwed up is to run the program on a big-endian architecture. So I'm interested in knowing (a) if it's even necessary to do these checks since Windows doesn't ordinarily run on little-endian platforms (today anyway), and (b) how I could possibly test my code, seeing as I can't think of a way to run Windows on a big-endian architecture, and manually reversing all the multibyte values on disk still involves a manual process that I might well screw up.

jgottula
  • 1,346
  • 2
  • 11
  • 17
  • 3
    endianness checks are (or should be) done at compile time, never runtime. The endianness of an architecture is intrinsic to the machine code generated - its a waste to check at runtime, something that was fixed at compile time. – Chris Becke Jun 23 '11 at 07:14
  • @Chris Becke, Good idea. I switched over to using ``, which has a preprocessor definition-based way of determining the byte order. This let me use conditional compilation to make the conversion functions one-liners rather than checking the endianness each time (which should make the functions entirely disappear when optimized on little-endian platforms, I believe). – jgottula Jun 24 '11 at 23:09
  • @ChrisBecke So is there any way to test the endianess at compile-time without using Boost? – Niklas R Nov 23 '15 at 15:51

2 Answers2

10

All versions of Windows that you'll see are little-endian, yes. The NT kernel actually runs on a big-endian architecture even today.

Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • About the Xbox360 it appears to be a misconception: https://blogs.msdn.microsoft.com/xboxteam/2006/02/17/the-xbox-operating-system/ – EFraim Aug 22 '17 at 08:03
  • 1
    Nope! It's the NT kernel. – Ana Betts Sep 20 '17 at 03:23
  • 1
    Lacking other evidence I tend to trust the XBox development blog – EFraim Sep 24 '17 at 09:07
  • The Blogs link is now "Oops! That page can’t be found." From the [horse's mouth](https://web.archive.org/web/20081220111118/http://blogs.msdn.com/xboxteam/archive/2006/02/17/534421.aspx): "I am honestly not sure where the Win2K misperception comes from, but Xbox runs a custom operating system built from the ground up." Big endian for sure. There are conflicting opinions over at [Reddit](https://www.reddit.com/r/emulation/comments/8by40b/original_xbox_emulation_still_not_possible_how/) as to what the kernel was actually based on. – Laurie Stearn Jan 28 '19 at 11:22
  • 5
    I'm confused by this answer. You're linking to the Wikipedia page of the XBox 360. How is that relevant? "_All versions of Windows are little-endian_" and then "_NT kernel runs on big-endian_". So all versions *except* the XBox OS? It would be great if you could either explain that in the answer or remove the second sentence. – Andreas Haferburg Sep 03 '21 at 14:16
  • FWIW, the OS on the Xbox360 is big-endian because the Xenon processor cores derived from the PowerPC architecture which is big-endian: https://en.wikipedia.org/wiki/Xenon_(processor). Also, the OS & kernel used in Xbox360 is a stripped-down OS/kernel based in large part on Windows, but very heavily customized for purpose, reducing unnecessary services, subsystems, abstraction layers, etc. However, while Windows COULD be rebuilt for big-endianness, for all "traditional" desktop and server platforms your code is likely to encounter, you can safely assume little endianness, inc. on Arm64. – Rich Turner Aug 31 '22 at 17:24
7

Edit after changed question:

A) No it is not necessary to check endianness if your sole target is Windows x86 or x64. I wouldn't even spend the time checking the endianness in that case.

B) If you want to check bi-endian support of your code I recommend splitting it into libraries that are themselves cross platform compilable. Then compile and run the code on your favorite Linux flavor that supports big-endian and see if it works. I have yet to hear of any compiler or software that can detect bi-endian issues.

Original response:

As far as I'm aware there are no desktop or server versions of windows that support big-endian. Itanium processors (which I believe were always called IA 64, not IA32 but I could be wrong) have the ability to run in big-endian but Windows doesn't support it.

This isn't to say that Windows 8 will be little-endian only as Windows 8 is targeting ARM processors.

If for some reason you are on Windows (#ifdef _WIN32) and big-endian simply reverse the data structures when you load from disk and just always save in little-endian format which is much more common.

NtscCobalt
  • 1,639
  • 2
  • 15
  • 31
  • I suspect that that code fragment reflects the endianness of the compiler rather than the target architecture which will be a problem when doing any kind of cross compiling - especially a problem when developing applications for smart phones – Chris Becke Jun 23 '11 at 07:35
  • @Chris Becke, I think you are right but I don't entierly understand how the >> operators work in preprocessor. Anyway there is a pretty detailed post about detection of endian in c that doesn't rely on preprocessor tricks here http://stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine – NtscCobalt Jun 23 '11 at 08:11
  • 2
    ARM is bi-endian, usually and by default little, it's very likely that Windows 8 on ARM will be little-endian, too. –  Jun 23 '11 at 11:29
  • I did test that code with GCC on an x86 iMac - and it (unfortunately) generated a little endian result for a PPC target. I'm pretty sure that PPC is always big endian. – Chris Becke Jun 24 '11 at 15:20
  • 1
    Runtime checks that depend on unions or pointer casts (taking the LSB out of a word and seeing if it's the first or last byte) work properly. Compile-time checks mostly seem to involve checking the architecture being compiled for by way of a preprocessor definition (at least, that seems to be how boost does it). – jgottula Jun 24 '11 at 23:07
  • @Chris Becke: I removed the code from my post. Thank you. I guess I will stick to using the predefined ____LITTLE_ENDIAN____ and ____BIG_ENDIAN____ on GCC and just always assume little endian on when _WIN32 is defined. – NtscCobalt Jun 26 '11 at 18:10
  • @ChrisBecke PPC is bi-endian, though it requires motherboard support to properly work. Practically everything uses big-endian mode, though. (Windows NT's PPC ports are some of the notable ones that don't, and IBM has been investing heavily in little-endian support for POWER8.) – gsnedders Mar 07 '16 at 22:10