Dữ liệu có thể được biểu diễn theo 2 cách nào? ý nghĩa của từng cách?

Bài viết gốc: //manhhomienbienthuy.github.io/2018/09/20/little-endian-vs-big-endian.html [đã xin phép tác giả

]

Little endian và big endian, đây là hai phương thức khác nhau để lưu trữ dữ liệu dạng nhị phân [binary]. Bình thường thì 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ẽ được tự động 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 ngôn ngữ 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ể chúng ta sẽ đọc sai thứ tự và xử lý với dữ liệu được hiểu sai.

Dữ liệu

Dữ liệu là thể hiện của thông tin dưới dạng lưu trữ được. Thông tin 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 chúng ta. Để lưu trữ, cũng như truyền đạt thông tin đến mọi người, chúng ta cần đến dữ liệu. Dữ liệu có thể là chữ viết, hình ảnh được ghi trên giấy, tất cả chúng ta dữ liệu mà con người có thể hiểu được.

Nhưng những dữ liệu đó cần phải được mã hoá một lần nữa, nếu chúng ta muốn lưu trữ chúng trên máy tính. Như chúng ta đều biết, máy tính chỉ làm việc với dữ liệu được mã hoá dưới dạng nhị phân, vậy nên mọi dữ 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 học cũng đang được phát triển, hy vọng trong vài năm tới, chúng ta sẽ update lại kiến thức về dữ liệu.

Thực ra, máy tính không hiểu được các ký tự 0, 1 trong hệ nhị phân đâu, nó hoạt động theo các tín hiệu điện tử. Mô tả chính xác thì rất khó, nhưng chúng ta có thể hiểu "sơ sơ" rằng, gặp bit 1 thì sẽ có 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à chúng ta coi đó như máy tính đã hiểu được dữ 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 ngôn ngữ. 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 các ký hiệu 0 hay 1, 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 cứ lúc nào, các máy tính cũng có thể hiểu được lẫn nhau.

Trong máy tính, các dữ 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 biểu diễn dưới dạng nhị phân sẽ là [ở đây tôi cho rằng kiểu dữ liệu int sẽ có kích thước là 4 byte, tuy nhiên, nhiều 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, 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 dữ liệu này trên đĩa cứng chẳng hạn, nó được ghi thế nào chưa. Bạn cho rằng, nó sẽ được ghi lần lượt theo thứ tự mà chúng ta đang đọc và viết ở trên, thì bạn đã nhầm.

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

Little endian và big endian là gì?

Little endian và big endian là hai phương thức khác nhau để lưu trữ dữ liệu. Sự khác biệt của little endian và big endian khi lưu trữ chính là ở việc sắp xếp thứ tự các byte dữ 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 biểu diễn nhị phân trên sẽ được ghi trước. Ví dụ 123456789 ghi theo kiểu little endian sẽ thành

15 cd 5b 07

Hơi ngược một chút đúng không? Big endian [xuất phát từ "big-end"] thì ngược lại, là cơ chế ghi dữ liệu theo thứ tự bình thường mà chúng ta vẫn dùng. 123456789 được lưu trữ vẫn theo đúng thứ 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 dữ liệu, còn thứ 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 dữ liệu có nhiều byte. Những dữ liệu chỉ có 1 byte [ví dụ ký tự ASCII] thì không ảnh hưởng gì [chính xác là dù dùng phương thức nào kết quả cũng như nhau]

Little endian và big endian được dùng trên những máy tính nào?

Việc sắp xếp các byte dữ liệu theo kiểu little endian hay big endian không chỉ xảy ra khi chúng ta lưu trữ dữ liệu ra bộ nhớ ngoài. Mọi hoạt động của máy tính đều sử dụng dữ 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 ngôn ngữ 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 đây 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 đây đều là big endian, nhưng hiện nay chúng cũng được nâng cấp thành bi-endian.

Các làm nào thì tốt hơn: little endian hay big 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ữ thứ tự các byte dữ liệu. Cả hai phương thức đều không làm ả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 bao giờ có thể có một câu trả lời thoả đáng: Phương thức nào thì tốt hơn?

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

Với giả định 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 phải thay đổi, chúng ta chỉ cần ghi tiếp các byte lớn hơn mà thôi.

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

Nhưng big endian cũng có nhưng lợi thế nhất định, với việc đọc dữ liệu byte lớn nhất 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 đầu tiên.

Xem các byte dữ liệu trong bộ nhớ

Chương trình C đơn giản nhau cho chúng ta cách nhìn về việc sắp xếp các byte trong bộ nhớ.

#include void show_mem_rep [char *start, int n] { int i; for [i = 0; i

Chủ Đề