Nội dung bài viết
STDIO Một bộ máy có thể đọc và xử lý dữ liệu được tạo ra bởi nó một cách bình thường. Vấn đề xảy ra khi một bộ máy “khác loại” cố gắng đọc dữ liệu đó. Thuật ngữ Big Endian và Little Endian diễn tả sự khác nhau về cách đọc và ghi dữ liệu giữa các nền tảng máy tính.

Giới thiệu

Cũng như con người, máy tính cũng "nói" các ngôn ngữ khác nhau. Một số “đọc” và “ghi” từ trái sang phải, trong khi một số khác thì ngược lại. Một bộ máy có thể đọc và xử lý dữ liệu được tạo ra bởi nó một cách bình thường. Vấn đề xảy ra khi một bộ máy “khác loại” cố gắng đọc dữ liệu đó. Thuật ngữ “big endian” và “little endian” diễn tả sự khác nhau về cách đọc và ghi dữ liệu giữa các nền tảng máy tính. Bài viết sẽ cung cấp cho các bạn một số kiến thức về big và little endian.

Tiền đề bài viết

Trong quá trình nghiên cứu, tôi đã bắt gặp hai thuật ngữ này và đã có sự đầu tư tìm hiểu. Được anh La Kiến Vinh :: www.stdio.vn/users/index/1/la-kien-vinh động viên, tôi đã tổng hợp lại kiến thức và chia sẻ với các bạn trong bài viết này.

Đối tượng hướng đến

Bài viết nói về cách lưu trữ bên dưới của máy tính, do đó nó dành cho các lập trình viên LOW LEVEL, nếu bạn có định hướng là lập trình viên ở mức HIGH LEVELvui lòng đọc ở mức độ xem như tham khảo.

Tổng quan

Endian là cách tổ chức dữ liệu trên một nền tảng máy tính. Bộ nhớ máy tính có thể được xem như một mảng có kích thước lớn, chia làm nhiều ô, mỗi ô có kích thước 1 byte. Nếu dữ liệu của bạn có thể được gói gọn trong 1 byte, nghĩa là mỗi lần bạn chỉ xử lý 1 byte thì không có gì khác biệt.

Vấn đề xảy ra khi dữ liệu của bạn vượt quá 1 byte, ví dụ như bạn cần lưu trữ một số nguyên. Khi đó 4 byte của biến số nguyên đó sẽ được lưu vào bộ nhớ máy tính theo thứ tự nào?

Big Endian

Đối với các nền tảng dùng big endian, Least Significant bit (LSB) luôn được lưu ở ô nhớ có địa chỉ lớn nhất còn Most Significant Bit (MSB) được lưu ở ô nhớ có địa chỉ nhỏ nhất trong vùng lưu trữ của biến. Trong đó, LSB là bit có trọng số nhỏ nhất, nằm ở ngoài cùng bên phải; MSB là bit có trọng số lớn nhất, nằm ở ngoài cùng bên trái của một biến.


Big Endian

Lưu trữ số nguyên 7411 vào bộ nhớ máy trên nền tảng dùng big endian. Ta cùng xét ví dụ sau:

Số 7411 được viết dưới dạng nhị phân như sau:

1 1100 1111 0011

Minh họa việc lưu số 7411 vào bộ nhớ máy tính như sau:

Big Endian

Các nền tảng sử dụng Big Endian

IBM zSeries, iSeries, AIX, NonStop Kernel, Motorola 68K…

Little Endian

Ngược lại với các nền tảng sử dụng big endian, ở các nền tảng sử dụng little endian, LSB luôn được lưu ở ô nhớ có địa chỉ nhỏ nhất còn MSB được lưu ở ô nhớ có địa chỉ lớn nhất trong vùng lưu trữ của biến.

Xét lại ví dụ trên, việc lưu trữ số nguyên 7411 vào bộ nhớ máy tính được minh họa như sau:

Little

Các nền tảng sử dụng Little Endian

Hầu hết các hệ thống sử dụng vi xử lý của Intel.

Ưu điểm của Big Endian và Little Endian

Big endian và little endian đều do con người sáng tạo nên và đều không gây ảnh hưởng đến tốc độ xử lý của CPU. Do đó sẽ không có câu trả lời hợp lý cho câu hỏi: cái nào lợi thế hơn cái nào?

Với big endian, do dữ liệu được ghi từ trái qua phải, bạn sẽ dễ dàng kiểm tra một số là số dương hay số âm do bit dấu được lưu trữ ở bit đầu tiên của biến. Ta không cần biết số đó chiếm bao nhiêu byte, cũng như không cần nhảy qua byte nào để xác định byte lưu trữ dấu của số đó. Các số cũng được lưu trữ đúng như trình tự mà nó được hiển thị, do đó sẽ hiệu quả trong phép toán đổi từ nhị phân sang thập phân.

Với little endian, một biến có thể được đọc với độ dài bất kì mà không cần phải thay đổi memory address. Do đó sẽ thuận tiện hơn trong các phép toán ép kiểu, chuyển kiểu, dễ dàng viết các phép toán phức tạp …

Chuyển đổi giữa Big Edian và Little Endian

Qua ví dụ ở trên, các bạn đã thấy được sự khác nhau giữa big endian và little endian. Điều này rất quan trọng trong lập trình đa nền tảng, vì các chương trình được viết ở nền tảng sử dụng big endian thì không thể sử dụng được các nền tảng khác sử dụng little endian. Muốn sử dụng được trước hết ta phải đồng bộ hai nền tảng bằng cách xem xét và đảo lại vị trí các byte cho phù hợp với hệ thống mới.

Codes C++ chuyển đổi qua lại giữa Little Endian và Big Endian.

// 2 bytes
void EndianSwap (unsigned short& x)
{
	x = (x >> 8) | (x << 8);
}

// 4 bytes
void EndianSwap (unsigned int& x)
{
	x = (x >> 24) |
		((x << 8) & 0x00FF0000) |
		((x >> 8) & 0x0000FF00) |
		(x << 24);
}

// 8 bytes
void EndianSwap (unsigned __int64& x)
{
	x = (x >> 56) |
		((x << 40) & 0x00FF000000000000) |
		((x << 24) & 0x0000FF0000000000) |
		((x << 8)  & 0x000000FF00000000) |
		((x >> 8)  & 0x00000000FF000000) |
		((x >> 24) & 0x0000000000FF0000) |
		((x >> 40) & 0x000000000000FF00) |
		(x << 56);
}
THẢO LUẬN
ĐÓNG