Skip to content

Commit

Permalink
Site updated: 2023-11-10 18:20:27
Browse files Browse the repository at this point in the history
  • Loading branch information
packetmania committed Nov 11, 2023
1 parent b478f36 commit 79759cc
Show file tree
Hide file tree
Showing 49 changed files with 99 additions and 99 deletions.
8 changes: 4 additions & 4 deletions 2021/12/24/Endianness/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: dark)">
<meta name="generator" content="Hexo 6.0.0">
<meta name="generator" content="Hexo 6.3.0">

<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
Expand Down Expand Up @@ -327,7 +327,7 @@ <h1 class="post-title" itemprop="name headline">
<p>How can I remember these two data storing modes? It is quite simple. First, remember that the addresses of the memory units we are talking about are always arranged from low to high. For a multi-byte number, if the first byte in the low address you see is the least-significant byte, the system is <code>Little Endian</code>, where Little matches <code>low</code>. On the contrary is <code>Big Endian</code>, where Big corresponds to "high".</p>
<h2 id="program-example">Program Example</h2>
<p>To deepen our understanding of Endianness, let's look at the following example of a C program:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">char</span> a = <span class="number">1</span>; </span><br><span class="line"><span class="keyword">char</span> b = <span class="number">2</span>; </span><br><span class="line"><span class="keyword">short</span> c = <span class="number">255</span>; <span class="comment">/* 0x00ff */</span></span><br><span class="line"><span class="keyword">long</span> d = <span class="number">0x44332211</span>;</span><br></pre></td></tr></table></figure>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">char</span> a = <span class="number">1</span>; </span><br><span class="line"><span class="type">char</span> b = <span class="number">2</span>; </span><br><span class="line"><span class="type">short</span> c = <span class="number">255</span>; <span class="comment">/* 0x00ff */</span></span><br><span class="line"><span class="type">long</span> d = <span class="number">0x44332211</span>;</span><br></pre></td></tr></table></figure>
<p>On Intel 80x86 based systems, the memory content corresponding to variables a, b, c, and d are shown in the following table:</p>
<table>
<thead>
Expand Down Expand Up @@ -356,11 +356,11 @@ <h2 id="program-example">Program Example</h2>
<li><code>Little Endian</code>: Intel x86, AMD64, DEC VAX</li>
</ul>
<p>How to detect the Endianess of local system in the program? The following function can be called for a quick check. If the return value is 1, it is <code>Little Endian</code>, else <code>Big Endian</code></p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">test_endian</span><span class="params">()</span> </span>&#123;</span><br><span class="line"> <span class="keyword">int</span> x = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> *((<span class="keyword">char</span> *)&amp;x);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">test_endian</span><span class="params">()</span> &#123;</span><br><span class="line"> <span class="type">int</span> x = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> *((<span class="type">char</span> *)&amp;x);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="network-order">Network Order</h2>
<p>Endianness is also important for computer communications. Imagine that when a <code>Little Endian</code> system communicates with a <code>Big Endian</code> system, the receiver and sender will interpret the data completely differently if not handled properly. For example, for the variable d in the C program segment above, the <code>Little Endian</code> sender sends <em>11 22 33 44</em> four bytes, which the <code>Big Endian</code> receiver converts to the value 0x11223344. This is very different from the original value. To solve this problem, the TCP/IP protocol specifies a special "network byte order" (referred to as "network order"), which means that regardless of the Endian supported by the computer system, the most-significant byte is always sent first while transmitting data. From the definition, we can see that the network order corresponds to the <code>Big Endian</code>.</p>
<p>To avoid communication problems caused by Endianness and to facilitate software developers to write portable programs, some C preprocessing macros are defined for conversion between network bytes and local byte order. <code>htons()</code> and <code>htonl()</code> are used to convert local byte order to network byte order, the former works with 16-bit unsigned numbers and the latter for 32-bit unsigned numbers. <code>ntohs()</code> and <code>ntohl()</code> implement the conversion in the opposite direction. The prototype definitions of these four macros can be found as follows (available in the <code>netinet/in.h</code> file on Linux systems).</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">if</span> defined(BIG_ENDIAN) &amp;&amp; !defined(LITTLE_ENDIAN)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> htons(A) (A)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> htonl(A) (A)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ntohs(A) (A)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ntohl(A) (A)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">elif</span> defined(LITTLE_ENDIAN) &amp;&amp; !defined(BIG_ENDIAN)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> htons(A) ((((uint16)(A) &amp; 0xff00) &gt;&gt; 8) | \</span></span><br><span class="line"><span class="meta"> (((uint16)(A) &amp; 0x00ff) &lt;&lt; 8))</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> htonl(A) ((((uint32)(A) &amp; 0xff000000) &gt;&gt; 24) | \</span></span><br><span class="line"><span class="meta"> (((uint32)(A) &amp; 0x00ff0000) &gt;&gt; 8) | \</span></span><br><span class="line"><span class="meta"> (((uint32)(A) &amp; 0x0000ff00) &lt;&lt; 8) | \</span></span><br><span class="line"><span class="meta"> (((uint32)(A) &amp; 0x000000ff) &lt;&lt; 24))</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ntohs htons</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ntohl htohl</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">else</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">error</span> <span class="meta-string">&quot;Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both.&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br></pre></td></tr></table></figure>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">if</span> defined(BIG_ENDIAN) &amp;&amp; !defined(LITTLE_ENDIAN)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> htons(A) (A)</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> htonl(A) (A)</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ntohs(A) (A)</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ntohl(A) (A)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">elif</span> defined(LITTLE_ENDIAN) &amp;&amp; !defined(BIG_ENDIAN)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> htons(A) ((((uint16)(A) &amp; 0xff00) &gt;&gt; 8) | \</span></span><br><span class="line"><span class="meta"> (((uint16)(A) &amp; 0x00ff) &lt;&lt; 8))</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> htonl(A) ((((uint32)(A) &amp; 0xff000000) &gt;&gt; 24) | \</span></span><br><span class="line"><span class="meta"> (((uint32)(A) &amp; 0x00ff0000) &gt;&gt; 8) | \</span></span><br><span class="line"><span class="meta"> (((uint32)(A) &amp; 0x0000ff00) &lt;&lt; 8) | \</span></span><br><span class="line"><span class="meta"> (((uint32)(A) &amp; 0x000000ff) &lt;&lt; 24))</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ntohs htons</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ntohl htohl</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">else</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">error</span> <span class="string">&quot;Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both.&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br></pre></td></tr></table></figure>

</div>

Expand Down
Loading

0 comments on commit 79759cc

Please sign in to comment.