Little endian vs. Big endian

Chúng tôi rất vui mừng được chia sẻ kiến thức sâu sắc về từ khóa Little endian la gi để tối ưu hóa nội dung trang web và chiến dịch tiếp thị trực tuyến. Bài viết cung cấp phương pháp tìm kiếm, phân tích và lựa chọn từ khóa phù hợp, cùng với chiến lược và công cụ hữu ích. Hy vọng thông tin này sẽ giúp bạn xây dựng chiến lược thành công và thu hút lưu lượng người dùng. Cảm ơn sự quan tâm và hãy tiếp tục theo dõi blog để cập nhật kiến thức mới nhất.

Nội dung bài viết gốc: https://manhhomienbienthuy.github.io/2018/09/20/little-endian-vs-big-endian.html (đã xin phép tác giả )

Bạn Đang Xem: Little endian vs. Big endian

Little endian và big endian, đây là hai phương thức khác nhau để lưu trữ tài liệu dạng nhị phân (binary). Thường ngày thì tất cả chúng ta cũng chẳng cần quan tâm đến chúng làm gì. Bởi mọi việc sẽ tiến hành tự động hóa hoá hết.

Thế nhưng có những tình huống, ví dụ khi phải xử lý các tập tin có cấu trúc, tập tin binary, nhất là những tập tin được ghi bằng tiếng nói khác, thì việc hiểu về little endian và big endian là rất quan trọng. Bởi nếu không, rất có thể tất cả chúng ta sẽ đọc sai trật tự và xử lý với tài liệu được hiểu sai.

Tài liệu là thể hiện của thông tin dưới dạng lưu trữ được. tin tức là thứ trừu tượng, không có hình dạng, đó là những hiểu biết về các sự vật, sự việc xung quanh tất cả chúng ta. Để lưu trữ, cũng như truyền đạt thông tin đến mọi người, tất cả chúng ta cần đến tài liệu. Tài liệu có thể là chữ viết, hình ảnh được ghi trên giấy, tất cả tất cả chúng ta tài liệu mà con người dân có thể hiểu được.

Nhưng những tài liệu đó cần phải được mã hoá một lần nữa, nếu tất cả chúng ta muốn lưu trữ chúng trên máy tính. Như tất cả chúng ta đều biết, máy tính chỉ thao tác với tài liệu được mã hoá dưới dạng nhị phân, vậy nên mọi tài liệu cần được mã hoá thành nhị phân mới có thể xử lý trên máy tính được.

Thực ra điều này chỉ đúng với máy tính số (digital electronic computer). Nghe nói hiện nay máy tính lượng tử, máy tính sinh vật học cũng đang rất được phát triển, hy vọng trong vài năm tới, tất cả chúng ta sẽ update lại tri thức về tài liệu.

Thực ra, máy tính không hiểu được những ký tự 0, 1 trong hệ nhị phân đâu, nó hoạt động theo những tín hiệu điện tử. Mô tả chuẩn xác thì rất khó, nhưng tất cả chúng ta có thể hiểu “sơ sơ” rằng, gặp bit 1 thì sẽ sở hữu dòng diện, gặp bit 0 thì không có. Như vậy, các bit 0, 1 được xử lý thành các tín hiệu điện tử tương ứng, và tất cả chúng ta coi đó như máy tính đã hiểu được tài liệu nhị phân.

Thế nhưng, mặc dù cùng sử dụng tín hiệu dạng nhị phân, các máy tính khác nhau cũng không thực sự nói chung một tiếng nói. Cũng giống như coi người vậy, khi nhìn các ký tự a, b, c có người hiểu, có người không. Máy tính khi nhìn vào các tín hiệu tương ứng với những ký hiệu 0 hay một, mỗi máy tính có thể hiểu theo một cách khác nhau.

Thế nhưng, rất may là các máy tính vẫn hoạt động theo những tiêu chuẩn chung, thế nên nó vẫn có thể giao tiếp với nhau được. Tuy nhiên, lưu ý rằng, không phải bất kỳ lúc nào, các máy tính cũng đều có thể hiểu được lẫn nhau.

Trong máy tính, các tài liệu nhị phân không được xử lý theo từng bit riêng lẻ, mà được xử lý thành từng khối 8 bit một, và đơn vị xử lý nhỏ nhất này gọi là byte.

Ví dụ, số nguyên 123456789 được trình diễn dưới dạng nhị phân sẽ là (ở đây tôi nhận định rằng kiểu tài liệu int sẽ sở hữu kích thước là 4 byte, tuy nhiên, nhiều khối hệ thống 64 bit đã nâng kích thước này lên 8 byte)

00000111 01011011 11001101 00010101

Để ngắn gọn, tất cả chúng ta có thể viết nó dưới dạng hexa như sau:

07 5b cd 15

Đã có bao giờ, bạn tự hỏi, khi ghi tài liệu này trên đĩa cứng chẳng hạn, nó được ghi thế nào chưa. Bạn nhận định rằng, nó sẽ tiến hành ghi tuần tự theo trật tự mà tất cả chúng ta đang đọc và viết ở trên, thì bạn đã nhầm.

Đây là cách viết theo phong cách số Ả rập cho tất cả chúng ta dễ hiểu thôi, máy tính không “đọc” các ký tự giống như tất cả chúng ta nên nó cũng không lưu trữ giống cách tất cả chúng ta viết các ký tự này ra đâu. Việc ghi tài liệu ra sao đó là lúc little endian và big endian được sử dụng đến.

Little endian và big endian là hai phương thức khác nhau để lưu trữ tài liệu. Sự khác biệt của little endian và big endian khi lưu trữ đó là ở việc sắp xếp trật tự các byte tài liệu.

Trong cơ chế lưu trữ little endian (xuất phát từ “little-end” nghĩa kết thúc nhỏ hơn), byte cuối cùng trong trình diễn nhị phân trên sẽ tiến hành ghi trước. Ví dụ 123456789 ghi theo phong cách little endian sẽ thành

15 cd 5b 07

Hơi ngược một tẹo đúng không ạ? Big endian (xuất phát từ “big-end”) thì trái lại, là cơ chế ghi tài liệu theo trật tự thường nhật mà tất cả chúng ta vẫn dùng. 123456789 được lưu trữ vẫn theo như đúng trật tự là

07 5b cd 15

Các thuật ngữ big-end hay little-end xuất phát từ cuốn tiểu thuyết Gulliver du ký (Gulliver’s Travels), trong đó nhân vật Lilliputans tranh luận về việc nên đập trứng bằng đầu to hay nhỏ.

Và ngành IT đã ứng dụng thuật ngữ ngày, tương đối giống với nghĩa gốc. Lưu ý rằng, little endian hay big endian chỉ khác nhau ở cách sắp xếp các byte tài liệu, còn trật tự từng bit trong byte thì giống nhau. Rất may, các máy tính vẫn có điểm trung này.

Thêm một lưu ý nữa rằng, little endian hay big endian chỉ khác biệt khi cần lưu trữ những tài liệu có nhiều byte. Những tài liệu chỉ có một byte (ví dụ ký tự ASCII) thì không tác động ảnh hưởng gì (đúng là dù dùng phương thức nào kết quả cũng như nhau)

Xem Thêm : Thương hiệu thời trang Gucci là gì? Hãng Gucci của nước nào?

Việc sắp xếp các byte tài liệu theo phong cách little endian hay big endian không chỉ xẩy ra khi tất cả chúng ta lưu trữ tài liệu ra bộ nhớ ngoài. Mọi hoạt động của máy tính đều sử dụng tài liệu nhị phân, nên little endian/big endian hiện hữu trong mọi hoạt động của máy tính.

Ngoài việc sử dụng little endian/big endian một phần phụ thuộc vào phần mềm (do lập trình viên cố ý sử dụng một trong hai loại, hoặc tiếng nói lập trình quy định trước), nó còn phụ thuộc vào bộ vi xử lý của chính máy tính đó.

Các bộ vi xử lý Intel đều sử dụng little endian, các bộ vi xử lý cả ARM trước đó cũng là little endian, nhưng hiện này ARM đã nâng cấp vi xử lý của mình thành bi-endian (tức là xử lý cả little endian và big endian).

Các bộ vi xử lý PowerPC và SPARK trước kia đều là big endian, nhưng hiện nay chúng cũng được nâng cấp thành bi-endian.

Little endian hay big endian cũng như tranh luận gốc về việc đập trứng, không có một phương thức nào thực sự tốt hơn phương thức nào.

Little endian hay big endian chỉ khác nhau ở việc lưu trữ trật tự các byte tài liệu. Cả hai phương thức đều không làm tác động ảnh hưởng đến tốc độ xử lý của CPU. Thế nên cả hai phương thức đều vẫn tồn tại song song và sẽ không còn bao giờ có thể có một câu vấn đáp thoả đáng: Phương thức nào thì tốt hơn?

Mỗi phương thức đều phải sở hữu những lợi thế nhất định. Với little endian, vì byte nhỏ nhất luôn nằm bên cạnh trái, nó sẽ được chấp nhận tất cả chúng ta đọc tài liệu với độ dài tuỳ ý. Nó sẽ rất thích hợp nếu tất cả chúng ta cần ép kiểu, ví dụ từ int thành long int.

Với giả thiết int là 4 byte, long int là 8 byte, nếu dùng little endian, khi ép kiểu, địa chỉ bộ nhớ không cần thiết phải thay đổi, tất cả chúng ta chỉ việc ghi tiếp các byte to hơn mà thôi.

Nhưng nếu cũng trường hợp đó, mà sử dụng big endian, thì tất cả chúng ta sẽ phải dịch địa chỉ bộ nhớ ngày nay thêm 4 byte nữa mới có không gian để lưu trữ.

Nhưng big endian cũng đều có nhưng lợi thế nhất định, với việc đọc tài liệu byte lớn số 1 trước, nó sẽ rất dễ dàng kiểm tra một số là âm hay dương, do byte chứa dấu được đọc trước hết.

Lớp học C đơn giản nhau cho tất cả chúng ta cách nhìn về việc sắp xếp các byte trong bộ nhớ.

#include <stdio.hvàgt; /* function to show bytes in memory, from location start to start+n */ void show_mem_rep (char *start, int n) { int i; for (i = 0; i < n; i++) printf (” %.2x”, start[i]); printf (“n”); } /* Main function to call above function for 0x01234567 */ int main () { int i = 0x01234567; show_mem_rep ((char *) &i, sizeof (i)); return 0; }

Khi thực thi lớp học trên, nếu máy của bạn là little endian thì kết quả sẽ là

67 45 23 01

còn nếu máy bạn là big endian thì nó sẽ hiển thị theo trật tự thông thường

01 23 45 67

Có cách nào để xác định máy tính của tất cả chúng ta là little endian hay big endian hay là không? Có vô số các phương pháp khác nhau, ở đây là một trong số những cách đó:

#include <stdio.hvàgt; int main () { unsigned int i = 1; char *c = (char *) &i; if (*c) printf (“Little endian”); else printf (“Big endian”); return 0; }

Với đoạn code đơn giản trên, c là con trỏ, nó trỏ đến vùng nhớ của biến i là một số nguyên. Bởi vì số nguyên là kiểu tài liệu nhiều byte, trong khí tài liệu của char chỉ là một byte mà thôi, nên *c sẽ trả về giá trị là byte trước hết của số nguyên i.

Nếu máy tính của tất cả chúng ta là little endian thì byte trước hết này sẽ là một trong, trái lại thì nó sẽ là 0.

Về cơ bản thì little endian hay big endian không có tác động ảnh hưởng lắm đến việc lập trình. Phần lớn các lập trình viên không cần quan tâm nhiều lắm, bởi mọi việc đã được những trình biên dịch/thông dich đảm nhiệm hết.

Tuy nhiên, một số trường hợp, tất cả chúng ta cần quan tâm, đặc biệt quan trọng khi chuyển đổi tài liệu giữa các máy tính khác nhau. Ví dụ: khi tất cả chúng ta cần xử lý một file có cấu trúc thế này, 4 byte trước hết là một số nguyên n, sau đó là n số nguyên, mỗi số chiếm 4 byte bộ nhớ, v.v…

Trong trường hợp này, khi nhận file được tạo ra từ một máy tính khác, việc nó được ghi theo phong cách little endian hay big endian rõ ràng là tác động ảnh hưởng rất nghiêm trọng, nếu sử dụng sai phương thức, tất cả chúng ta sẽ thu về tài liệu sai.

Một trường hợp khác nữa có thể xẩy ra vấn đề là lúc tất cả chúng ta ép kiểu cho những biến

#include <stdio.hvàgt; int main () { unsigned char arr[2] = { 0x01, 0x00 }; unsigned short int x = *(unsigned short int *) arr; printf (“%d”, x); return 0; }

Trong đoạn code trên, tất cả chúng ta đã ép kiểu một array hai thành phần char thành một số nguyên 2 byte (short int). Trong ví dụ này, little endian hay big endian cũng đều có tác động ảnh hưởng rất lớn.

Xem Thêm : Canbus là gì? Có cần canbus khi lên màn hình android?

Một máy tính dùng little endian sẽ sở hữu kết quả là một trong trong những lúc big endian sẽ cho kết quả là 256. Để tránh những lỗi không hề muốn có thể xẩy ra, những code như trên cần phải tránh.

NUXI là một vấn đề rất nổi tiếng liên quan đến little endian và big endian: UNIX được lưu trong một khối hệ thống big-endian sẽ tiến hành hiểu là NUXI trong một khối hệ thống little endian.

Giả sử tất cả chúng ta cần lưu trữ 4 byte (U, N, I, X) bằng hai số nguyên dạng short int: UN và IX.

#include <stdio.hvàgt; int main () { short int *s; // pointer to set shorts s = (short int *)malloc(sizeof(short int)); // point to location 0 *s = “UN”; // store first short: U * 256 + N (fictional code) s += 2; // point to next location *s = “IX”; // store second short: I * 256 + X return 0; }

Đoạn code trên hoàn toàn độc lập với khối hệ thống, bất kể nó là little hay big endian. Nếu tất cả chúng ta lưu trữ các giá trị “UN” và “IX” khi đọc ra, nó vẫn sẽ là “UNIX” hay là không? Nếu mọi việc chỉ xẩy ra trên một máy tính, dù là big endian hay little endian thì nó sẽ luôn là như vậy, bởi mọi thứ sẽ tiến hành tự động hóa hoá giúp tất cả chúng ta.

Với bất kỳ tài liệu nào thì cũng vậy, tất cả chúng ta luôn thu được tài liệu đúng nếu đọc và ghi trong cùng một khối hệ thống. Thế nhưng, hãy xem xét kỹ hơn về việc sắp xếp các byte trong bộ nhớ.

Một khối hệ thống big endian sẽ lưu trữ như sau:

U N I X

Còn một khối hệ thống little endian thì sẽ như sau:

N U X I

Mặc dù trông hơi ngược nhưng khối hệ thống little endian sẽ xử lý việc đọc giúp tất cả chúng ta, nên lưu trữ như vậy nhưng khi lấy ra tất cả chúng ta vẫn có tài liệu ban sơ. Thế nhưng khi tất cả chúng ta ghi tài liệu này ra file, chuyển sang một máy tính khác. Và mỗi máy tính lại xử lý Theo phong cách riêng của nó thì UNIX trên máy big endian sẽ tiến hành hiểu là NUXI trên máy little endian (và trái lại).

Đây đó là vấn đều nguy hiểm nhất lúc tất cả chúng ta trao đỏi tài liệu qua lại giữa các máy tính với nhau, đặc biệt quan trọng trong thời đại Internet ngày này.

Ngày này, mọi máy tính đều được kết nối để trao đổi tài liệu với nhau. Little endian hay big endian cũng đều phải trao đổi với nhau, nhưng làm thế nào để sở hữu hiểu được nhau khi chúng không nói chung một thứ tiếng?

Có 2 giải pháp chính cho việc này

Sử dụng chung định dạng

Một phương án đơn giản nhất tất cả sử dụng chung một định dang khi truyền tài liệu.

Ví dụ những tập tin dạng PNG đều rất cần được sử dụng big endian. Tương tự với những tập tin có cấu trúc khác. Đó là lý do vì sao tất cả chúng ta nhiều khi cần phải dùng những phần mềm chuyên sử dụng để đọc và ghi các file này.

Thế nhưng trong kết nối với Internet, việc truyền tài liệu còn phức tạp hơn thế. Tất cả chúng ta không thể cứ dùng một định dạng file nào đó, rồi truyền từng byte một sang máy khác được. Muốn tăng tốc độ, bắt buộc tất cả chúng ta phải truyền nhiều byte một lúc.

Và khi đó tất cả chúng ta cần có một chuẩn chung. Hiện nay, chuẩn chung cho việc truyền tài liệu trên mạng, gọi là network byte order đó là big endian. Thế nhưng, dù đã chuẩn chung rồi, thỉnh thoảng vẫn có những giao thức chơi chội hơn, sử dụng little endian.

Để sở hữu thể chuyển đổi tài liệu thành tài liệu chuẩn theo network byte order, lớp học cần gọi hàm hton* (host-to-network) (trong tiếng nói C). Trong khối hệ thống big endian, hàm này sẽ không cần làm gì cả, còn little endian sẽ thực hiện chuyển đối các byte một tẹo.

Dù khối hệ thống big endian không cần chuyển đổi tài liệu, việc gọi hàm này vẫn là rất cấp thiết. Lớp học của tất cả chúng ta có thể được viết bằng một tiếng nói (C) nhưng có thể được dịch và thực thi ở nhiều khối hệ thống khác nhau, việc gọi hàm này sẽ giúp tất cả chúng ta làm điều đó.

Tương tự, ở chiều trái lại, tất cả chúng ta cần gọi hàm ntoh* để chuyển đổi tài liệu nhận được từ mạng về tài liệu máy tính có thể hiểu được. Ngoài ra, tất cả chúng ta còn phải nắm vững kiểu tài liệu mà tất cả chúng ta cần chuyển đổi nữa, list các hàm chuyển đổi như sau:

  • htons – “Host to Network Short”
  • htonl- “Host to Network Long”
  • ntohs – “Network to Host Short”
  • ntohl – “Network to Host Long”

Những hàm này vô cùng quan trọng khi thực hiện chia sẽ tài liệu trên tầng thấp, ví dụ khi kiểm tra checksum của rất nhiều gói tin chẳng hạn. Nếu không nắm vững về little endian và big endian thì khi cần thao tác về mạng, các bạn sẽ gặp nhiều khó khăn.

Sử dụng BOM (Byte Order Mark)

Một phương án khác để giải quyết và xử lý sự khác biệt về endian là sử dụng BOM (Byte Order Mark). Đây là một ký tự đặc biệt quan trọng, có mức giá trị là 0xFEFF, được ghi ở vị trí trước hết của file.

Nếu độc giả ký tự này là 0xFFFE (bị ngược) thì có nghĩa file này được ghi với endian khác với khối hệ thống của bạn, khi đó, các bạn sẽ cần phải thay đổi phương thức đọc tài liệu một tẹo.

Có một vài vấn đề nhỏ với việc sử dụng BOM. Thứ nhất, BOM sẽ gây nên tăng tài liệu được ghi vào file. Ngay cả những lúc tất cả chúng ta chỉ gửi đi 2 byte tài liệu, tất cả chúng ta vẫn cần thêm 2 byte BOM nữa.

Thứ hai, BOM không hoàn toàn thần thánh, bởi vì nó phụ thuộc vào lập trình viên. Có người dân có tâm thì đọc và xử lý khi gặp BOM, có người thì hoàn toàn bỏ quên nó và coi nói như tài liệu thông thường. Unicode sử dụng BOM khi lưu trữ tài liệu nhiều byte (nhiều ký tự Unicode được mã hoá thành 2, 3 thậm chí còn là 4 byte).

You May Also Like

About the Author: v1000

tỷ lệ kèo trực tuyến manclub 789club