Literature

url: https://uquest.tktk.co.jp/embedded/learning/lecture05.html
title: "Endianってなに? | 技術コラム | 東光高岳"
description: "ユークエストは株式会社東光高岳の一部門として、USBや無線LANなどの組込みソフトウェアや、4G/5G/LPWAを活用したIoTインテグレーションを提供します。"
host: uquest.tktk.co.jp
favicon: https://uquest.tktk.co.jp/assets/img/common/favicon.svg
image: https://uquest.tktk.co.jp/assets/img/common/og_img.png
url: https://atmarkit.itmedia.co.jp/icd/root/00/49717200.html
title: "Insider's Computer Dictionary�F���g���G���f�B�A�� �Ƃ́H - ��IT"
host: atmarkit.itmedia.co.jp
url: https://developer.mamezou-tech.com/blogs/2025/07/01/when_two_rights_collide/
title: "【IT業界雑学】「2つの正義」が交わるとき:ソフトウェアに潜む標準分裂の正体 | 豆蔵デベロッパーサイト"
description: "はじめに:業界に潜む「2つの標準」問題#ソフトウェア開発の世界には、仕様や動作が2つに分かれる“標準の分裂”現象がしばしば存在します。「どっちが正しいの?」という話になりがちですが、実際にはそれぞれ歴史的・技術的背景があるだけだったりします。今回は、そんな「2つの標準」にまつわる例をいくつか紹介します。配列って「0」から?それとも「1」から? 〜使う言語で変わる“常識”〜#プログラミング言語によって、配列の添え字(インデックス)の起点は大きく3つのパターンに分かれます..."
host: developer.mamezou-tech.com
favicon: https://developer.mamezou-tech.com/img/favicon-32x32.png
image: https://developer.mamezou-tech.com/og/?title=%E3%80%90IT%E6%A5%AD%E7%95%8C%E9%9B%91%E5%AD%A6%E3%80%91%E3%80%8C2%E3%81%A4%E3%81%AE%E6%AD%A3%E7%BE%A9%E3%80%8D%E3%81%8C%E4%BA%A4%E3%82%8F%E3%82%8B%E3%81%A8%E3%81%8D%EF%BC%9A%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AB%E6%BD%9C%E3%82%80%E6%A8%99%E6%BA%96%E5%88%86%E8%A3%82%E3%81%AE%E6%AD%A3%E4%BD%93&category=%E3%83%96%E3%83%AD%E3%82%B0

前提知識

コンピュータで扱うメモリには、1 つのアドレスにつき 1 byte 格納できます。 byte を単位とするデータを格納したい場合、アドレス から まで (: 右開区間) に連続して 1 byte ずつデータを格納します。

LittleEndian とは

2 byte 以上を単位とするデータ について、それを byte 単位で並べるときの順序を endian とよびます。 そして、「最下位のバイト」 からメモリアドレスへ昇順に格納する・転送するフォーマットを little-endian と呼びます。

注意点

2 byte 以上を単位とするデータ のときにエンディアンを考慮する必要がある、ことに注意が必要です。 1 byte を単位とするデータについてはエンディアンを考慮することなく、メモリアドレスにそのまま昇順に格納されます。

たとえば char text[10] = "hello"; を考えてみます。 char は 1 byte 単位のため、1 つのメモリアドレスで簡潔します。 よって、連続したアドレスに昇順に “h”, “e”, … といれるだけでよいです。

0x0000000000000000
------------
 
0x0000000001000050: "h"
0x0000000001000051: "e"
0x0000000001000052: "l"
0x0000000001000053: "l"
0x0000000001000054: "o"
...
 
------------
0xFFFFFFFFFFFFFFFF

Example

下記のように異なる型のデータを用意し、 gdb で覗いてみます。

typename
long long (8byte)value
int (4byte)value2
char (1byte) [10]text
#include <stdio.h>
 
int main() {
    long long value = 0x12345678152637;
    printf("Address of value: %p\n", &value);
 
    int value2 = 0x728171;
    printf("Address of value2: %p\n", &value2);
 
    char text[10] = "hello";
    printf("text: %s\n", text);
 
    return 0;
}

long long の値 value は 0x7fffffffe9f8 から 0x7fffffffe9ff の 8 byte にわたって格納されています。 具体的には value = 0x0012345678152637 = 5124095567275575 が「最下位のバイト」、つまり下の桁から 1 byte の単位で格納されています。

たしかに x/8bx で 1byte 単位でメモリを読み出すと 0x7fffffffe9f8 = 0x37, 0x7fffffffe9f9: 0x26 のように最下位のバイトから書き込まれていることがわかります。

0x0000000000000000
------------

0x7fffffffe9f8: 0x37
0x7fffffffe9f9: 0x26
0x7fffffffe9fa: 0x15
...
0x7fffffffe9ff: 0x00

------------
0xFFFFFFFFFFFFFFFF
(gdb) x/1gx &value
0x7fffffffe9f8: 0x0012345678152637
(gdb) x/8bx &value
0x7fffffffe9f8: 0x37    0x26    0x15    0x78    0x56    0x34    0x12    0x00

同様に int の値 value2 についても確認してみます。 value2 = 0x00728171 = 7504241 が最下位バイトから 1 byte ずつ格納されています。

(gdb) x/1wx &value2
0x7fffffffe9f4: 0x00728171
(gdb) x/4bx &value2
0x7fffffffe9f4: 0x71    0x81    0x72    0x00

char[10] の text については注意が必要です。 char は 1byte のデータ型であり、そもそもエンディアンを考慮しなくてよいです。

そのため、アドレス昇順でそのままデータが入っています。

(gdb) x/c &text
0x7fffffffe9ea: 104 'h'
(gdb) x/8c &text
0x7fffffffe9ea: 104 'h' 101 'e' 108 'l' 108 'l' 111 'o' 0 '\000'        0 '\000' 0 '\000'
(gdb) x/8bx &text
0x7fffffffe9ea: 0x68    0x65    0x6c    0x6c    0x6f    0x00    0x00    0x00