Tôi có biết cơ bản, nhưng vẫn không hiểu được bản chất tại sao nó lại hoạt động được như thế. Làm sao mà cái máy tính lại hiểu được những dòng code ấy nhỉ? Sao mà nó lại “biết” được ý nghĩa của những lệnh tôi viết để mà làm theo?
Chuỗi 1 và 0 này được đưa vào Vi xử lý từ RAM (Bộ nhớ/ Memory). Từng khối lệnh của các chương trình được lưu ở RAM, bao gồm những câu lệnh điều kiện để báo cho Vi xử lý biết “chạy đoạn code này nếu điều kiện này đúng, còn không thì chạy vào đoạn code này”. Trong các chương trình có thể câu lệnh như cộng 2 số trong RAM và ghi lại kết quả tính được vào 1 vị trí khác trên RAM, hoặc lắng nghe tín hiệu vào từ bàn phím, hoặc gửi thông tin ra loa hay màn hình, kiểu kiểu vậy. Bạn có thể ghép những câu lệnh trên lại với nhau để chỉ cho máy tính làm việc: “nếu nút spacebar được nhấn thì phát âm thanh, còn không nhấn thì không làm gì”.
Chuỗi lệnh nói trên (được gọi là hợp ngữ, assembly language) vẫn rất khó nhằn với lập trình viên. Vậy nên ta cần trình biên dịch (compiler). Trình biên dịch đơn giản là 1 chương trình máy tính có chức năng chuyển đổi ngôn ngữ lập trình từ lập trình viên viết ra thành hợp ngữ. Đó là cách mà hầu hết các ngôn ngữ lập trình hoạt động.
Dù những thứ mà bộ vi xử lý thực hiện nghe qua rất là cơ bản, nhưng nó được thiết kế để làm những thứ cơ bản như thế trong khoảng thời gian cực kỳ nhanh, lên đến hàng trăm triệu lệnh trên 1s. Có 1 khái niệm trong lý thuyết tính toán là Turing-completeness: khi kết hợp các lệnh trong 1 tập lệnh hữu hạn thì ta có thể thực hiện được bất kỳ bài toán logic nào miễn là có đủ thời gian. Máy tính hoạt động theo nguyên lý cơ bản này, nó có thể thực hiện bất kỳ 1 thao tác logic nào nếu đưa cho nó đủ lệnh chỉ dẫn và nó sẽ chạy đống lệnh đó 1 cách nhanh không tưởng tượng được. Việc ngồi code cũng chỉ là viết lệnh cho máy tính chạy, có thể là trực tiếp hoặc từ sự trợ giúp của trình biên dịch
Khi mà ta viết code, thứ mà chúng ta gõ ra được gọi là “ngôn ngữ bậc cao” (high level language HLL) hay “ngôn ngữ lập trình”. Những ngôn ngữ này thường là C, Java, Python, Ruby, Php, JavaScript, … chắc là bạn có thể nghe đến chúng ở đâu đó rồi. Con người chúng ta có thể dễ dàng đọc được những ngôn ngữ này, nhưng mà máy tính lại không thể hiểu chúng một cách trực tiếp như chúng ta.
Nên cái mà ta cần bây giờ là trình biên dịch (compiler). Trình biên dịch là chương trình máy tính có chức năng đọc file code bằng ngôn ngữ lập trình của lập trình viên viết và chuyển đổi chúng thành mã máy để máy hiểu được.
Lưu ý rằng đối với máy tính thì mọi thứ là số. Tất cả là 1 hoặc 0. Ta có thể quy ước số nào đó sẽ là đại diện màu nào đó, hoặc là 1 thời điểm, cũng có thể biểu diễn cho 1 lệnh mã máy. Ví dụ, chương trình bảo cho máy tính ghi một số giá trị vào 1 vùng của RAM, những giá trị đấy ứng với màu sắc mà màn hình có thể hiển thị. Với ý tưởng như thế, chương trình bảo máy tính viết những giá trị khác nữa vào RAM để kết hợp với nhau thành chuỗi text trên màn hình, vậy là ta có thể lướt f33 đọc báo được rồi.
1 chương trình có thể là 1 tập các mã máy để làm những thứ như “LOAD giá trị từ RAM vào CPU”, “ADD 32 vào giá trị đấy trong CPU” và “STORE giá trị từ CPU vào RAM”. Nhưng mà mọi thứ trong máy tính là số cơ mà nhỉ, vậy thì các đoạn mã máy trên cũng phải là số chứ. Nếu ta có 1 con số kiểu 1201123456, thì máy tính sẽ hiểu 2 số đầu là mã lệnh (operation code “opcode”). Tiếp tục, hãy coi số 12 như là lệnh “LOAD giá trị từ RAM vào CPU”, tiếp đến với 2 chữ số “01” chỉ ra vị trí trong CPU để ghi data vào, và 6 số cuối cùng “123456” là địa chỉ trong RAM để lấy data ra.
Vấn đề là trong máy tính, bộ nhớ trong CPU là thứ cực kỳ nhỏ (TN: trong CPU có 1 loại bộ nhớ là Register, chỉ để lưu các giá trị để tính toán tức thời). Nó không thể giữ nhiều dữ liệu để làm việc trong cùng 1 lúc được. Vì thế, ta phải liên tục nạp dữ liệu mới vào CPU, xử lý, rồi lưu lại kết quả vào chỗ nào đó. RAM có dung lượng lớn hơn nhưng tốc độ chậm hơn CPU. Nó có thể giữ hàng triệu con số. Và ta còn có ổ cứng để lưu được cực nhiều dữ liệu và tất nhiên nó lại chậm ơi là chậm. Ổ cứng có thể lưu hàng tỉ con số hoặc hơn. Vậy nên khi bạn muốn tính một phép toán, CPU đầu tiên sẽ đi tìm trong giá trị toán hạng đó có trong nó hay không. Nếu không có trong CPU, CPU sẽ đi tìm trong RAM. Nếu trong RAM vẫn không có, CPU lại đi tìm trong ổ cứng (hoặc từ internet hay từ chỗ nào đó tương tự).
Túm lại: Con người code với 1 loại ngôn ngữ lập trình nào đấy. Trình biên dịch sẽ dịch ngôn ngữ lập trình thành mã máy. Mã máy là những con số để chỉ dẫn cho CPU làm việc. CPU chỉ việc di chuyển data qua lại và làm vài phép tính toán đơn giản thôi.
Và bất kỳ đoạn trong comment này đều có thể viết ra được cả quyển sách, vậy nên nếu có thắc mắc gì thì hãy để lại câu hỏi dưới phần bình luận nhé.