
Assembly (hợp ngữ), một ngôn ngữ lập trình ra đời từ những năm 1950, đã dần nhường chỗ cho các ngôn ngữ bậc cao hơn như C và Pascal. Trong khoảng ba thập kỷ qua, gần như không có dự án phần mềm ứng dụng nào yêu cầu lập trình viên viết hoàn toàn bằng Assembly. Điều này là dễ hiểu, bởi lập trình Assembly đòi hỏi thao tác trực tiếp trên từng thanh ghi, từng ô nhớ, khiến ngay cả một chương trình “Hello, world!” cũng trở nên phức tạp.
Vậy câu hỏi đặt ra là: Assembly đã hoàn toàn biến mất chưa?
Thực tế là chưa. Trong một số tình huống đặc thù, thường là khi cần can thiệp sâu vào hệ thống, Assembly là lựa chọn duy nhất và bắt buộc. Dưới đây là một số trường hợp thực tế:
1. Tối ưu Hiệu năng Tuyệt đối
Trong các thư viện hệ thống, nơi mỗi chu kỳ CPU đều được tính toán, Assembly được dùng để tối ưu hóa các hàm tính toán quan trọng.
Lấy ví dụ hàm chuyển đổi giây sang giờ (chia cho 3600) trong các thư viện C chuẩn. Nếu để trình biên dịch C tự tối ưu, nó có thể sử dụng phép tính dấu phẩy động (floating-point), vốn tốn rất nhiều chu kỳ CPU. Thay vào đó, các kỹ sư viết thư viện này bằng Assembly, sử dụng các phép toán số nguyên và dịch bit (bit shift) cực kỳ thông minh, dựa trên tính chất của số 3600, để thực hiện phép chia. Kết quả là một hàm có thể chạy nhanh hơn gấp hàng chục lần so với phiên bản C thông thường.

2. Giai đoạn Khởi động Hệ thống (Boot Process)
Những đoạn mã đầu tiên của bootloader và hệ điều hành phải chạy trong một môi trường cực kỳ hạn chế. Ở thời điểm này, các tính năng cơ bản của chip như STACK (ngăn xếp) và HEAP (vùng nhớ động) chưa hề được khởi tạo.
Nếu không có STACK, các khái niệm cơ bản của C như “hàm con” (function call) hay “mảng” (array) không thể hoạt động. Một khai báo đơn giản như char a[10]; sẽ gây lỗi, vì hệ thống chưa biết cấp phát bộ nhớ cho mảng đó ở đâu.
Do đó, Assembly là ngôn ngữ duy nhất đủ “cơ bản” để chạy trong môi trường sơ khai này, thực hiện nhiệm vụ thiết lập STACK, HEAP, và các thanh ghi điều khiển thiết yếu trước khi “bàn giao” quyền kiểm soát lại cho các đoạn mã C.
3. Xử lý Đồ họa và Đa phương tiện
Mặc dù các ngôn ngữ bậc cao đã thống trị, nhưng trong lĩnh vực yêu cầu hiệu năng cực cao như xử lý hình ảnh và card đồ họa, Assembly vẫn có vai trò quan trọng. Các tác vụ lặp đi lặp lại hàng triệu lần (như dịch chuyển, xoay ảnh, giải mã video) thường được viết bằng các tập lệnh Assembly chuyên biệt (ví dụ: SIMD) để đạt được tốc độ xử lý nhanh nhất mà phần cứng cho phép.
4. Đảm bảo Tính Độc lập của Hệ thống
Một trường hợp thú vị khác là khi cần viết một thư viện được nạp vào RAM và phải chạy được ở cả kernel space và user-space. Nếu viết thư viện này bằng C và vô tình gọi một hàm như printf(), trình biên dịch sẽ liên kết nó với thư viện glibc (một thư viện user-space). Thư viện này không thể chạy được trong kernel space, dẫn đến crash hệ thống.
Viết bằng Assembly cho phép kỹ sư tạo ra một đoạn mã “tự chứa” (self-contained), hoàn toàn độc lập, không phụ thuộc vào bất kỳ thư viện bên ngoài nào, đảm bảo nó có thể được thực thi an toàn ở mọi mức đặc quyền của hệ thống.
Kết luận
Ở thời điểm hiện tại, dù các ngôn ngữ bậc cao rất phát triển, một lập trình viên thông thường có thể không bao giờ “nhìn thấy” Assembly. Tuy nhiên, ở tầng sâu nhất của hệ thống, Assembly vẫn là một công cụ không thể thay thế. Nó là cây cầu nối trực tiếp và hiệu quả nhất giữa phần mềm và phần cứng, và có lẽ trong tương lai xa, vai trò nền tảng này vẫn sẽ rất khó bị thay thế.
