{"id":4579,"date":"2013-03-18T12:11:49","date_gmt":"2013-03-18T11:11:49","guid":{"rendered":"https:\/\/blogs.mentor.com\/colinwalls\/?p=4579"},"modified":"2013-03-18T12:11:49","modified_gmt":"2013-03-18T11:11:49","slug":"endianness","status":"publish","type":"post","link":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/2013\/03\/18\/endianness\/","title":{"rendered":"Endianness"},"content":{"rendered":"<p>In almost all modern embedded systems, memory is organized into bytes. CPUs, however, process data as 8-, 16- or 32-bit words. As soon as this word size is larger than a byte, a decision needs to be made with regard to how the bytes in a word are stored in memory. There are two obvious options and a number of other variations. The property that describes this byte ordering is called &#8220;<a href=\"http:\/\/en.wikipedia.org\/wiki\/Endianness\" target=\"_blank\" rel=\"noopener noreferrer\">endianness<\/a>&#8221; [or, sometimes, &#8220;endianity&#8221;].<\/p>\n<p>Broadly speaking, the endianness in use is determined by the CPU. Because there are a number of options, it is unsurprising that different semiconductor vendors have chosen different endianness for their CPUs. The questions, from an embedded software engineers perspective are &#8220;Does endianness matter?&#8221; and &#8220;If so, how much?&#8221; &#8230;<!--more--><\/p>\n<p>First of all we need to provide some boundaries for this discussion. I am going to just consider 32-bit CPUs &#8211; the same issues apply to 16- and 64-bit devices. Even 8-bit devices typically have instructions that deal with larger data units. I am also going to limit my consideration to the obvious endianness options: least significant byte stored at lowest address [&#8220;little-endian&#8221;] and most significant byte stored at lowest address [&#8220;big-endian&#8221;]. These two options may visualized quite easily:<\/p>\n<p><a href=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/51\/2013\/03\/500px-Big-Endian.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-4583 alignleft\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/51\/2013\/03\/500px-Big-Endian.png\" alt=\"\" width=\"245\" height=\"218\" \/><\/a><a href=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/51\/2013\/03\/500px-Little-Endian.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-4587\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/51\/2013\/03\/500px-Little-Endian.png\" alt=\"\" width=\"245\" height=\"218\" \/><\/a><\/p>\n<p>There are also other possibilities, like using little-endian within 16-bit words, but storing the 16-bit words inside 32-bit words using big-endian. This is commonly called &#8220;middle-endian&#8221; or &#8220;mixed-endian&#8221;, but rarely encountered nowadays. The order of bits within a byte is also potentially arbitrary, but I will ignore that too.<\/p>\n<p>Examples of little-endian CPUs include Intel x86 and Altera Nios II. Big-endian CPUs include Freescale 68K and Coldfire and Xilinx Microblaze. Many modern architectures facilitate both modes and can be switched in software; such &#8220;bi-endian&#8221; devices include ARM, PowerPC and MIPS.<\/p>\n<p>There are broadly two circumstances when a software developer needs to think about endianness:<\/p>\n<ul>\n<li>data transmitted over a communications link or network<\/li>\n<li>data handled in multiple representations in software<\/li>\n<\/ul>\n<p>The former situation is quite straightforward &#8211; simply a matter of following or defining a protocol. The latter is more tricky and requires some thought.<\/p>\n<p>Consider this code:<\/p>\n<pre>unsigned int n = 0x0a0b0c0d;<\/pre>\n<pre>unsigned char c, d, *p;<\/pre>\n<pre>c = (unsigned char) n;<\/pre>\n<pre>p = (unsigned char *) &amp;n;<\/pre>\n<pre>d = *p;<\/pre>\n<p>&nbsp;<\/p>\n<p>What values would <strong>c<\/strong> and <strong>d<\/strong> contain at the end? Whatever the endianness, <strong>c<\/strong> should contain the value <strong>0x0d<\/strong>. However, the value of <strong>d<\/strong> will depend on the endianness. On a little-endian system <strong>d<\/strong> will contain <strong>0x0d<\/strong>; on big-endian it will have the value <strong>0x0a<\/strong>. The same kind of effect would be observed if a <strong>union<\/strong> were to be made between <strong>n<\/strong> and, say, <strong>unsigned char a[4]<\/strong>.<\/p>\n<p>So, does this matter? With care, most code may be written to be independent of endianness and I would contend that almost all well-written code would be like this. However, if you do build in an endianness dependency, as usual, good documentation\/commenting is obviously essential.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In almost all modern embedded systems, memory is organized into bytes. CPUs, however, process data as 8-, 16- or 32-bit&#8230;<\/p>\n","protected":false},"author":71677,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spanish_translation":"","french_translation":"","german_translation":"","italian_translation":"","polish_translation":"","japanese_translation":"","chinese_translation":"","footnotes":""},"categories":[1],"tags":[313,300,519,520],"industry":[],"product":[],"coauthors":[],"class_list":["post-4579","post","type-post","status-publish","format-standard","hentry","category-news","tag-c","tag-embedded-software","tag-endianity","tag-endianness"],"_links":{"self":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/4579","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/users\/71677"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/comments?post=4579"}],"version-history":[{"count":0,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/4579\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/media?parent=4579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/categories?post=4579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/tags?post=4579"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/industry?post=4579"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/product?post=4579"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.stage.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/coauthors?post=4579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}