Trang nhà > Công nghệ > Thông tin > Không làm gì vẫn là làm
Không làm gì vẫn là làm
Thứ Bảy 2, Tháng Giêng 2021, bởi
Trong tập chỉ thị của bộ xử lý có một thao tác điều khiển máy gọi là "NOP" (no operation: không hoạt động). Câu hỏi là tại sao ta cần có NOP trong khi đã có chỉ thị HLT (halt: dừng hoạt động) hoặc RST (reset: khởi động lại). Và tại sao lại là NOP? Nó cần thiết cho ai?
NOP là gì
Đó là một chỉ thị ít người để ý đến vì tưởng rằng nó chả làm gì cả khi không thực hiện thao tác nào. Bản thân điều này có thể làm ta liên tưởng tới “nghịch lý thợ cạo” của nhà toán học kiêm triết gia Bertrand Russell “a set of all sets that are not members of themselves – is it a member of itself?” (“một tập hợp của tất cả các tập hợp không phải là thành phần của chính chúng thì tập hợp đó có phải là một thành phần của chính nó hay không?”), thường được kể dưới dạng chuyện vui là “Nếu tôi chỉ cạo râu cho những người không tự cạo râu, thì tôi có tự cạo râu không?”. [1]
Nhà triết học toán học Göttlob Frege cho rằng nghịch lý Russell là một “run sợ về thuật toán”. Sau đó, để tránh sai lầm trên, người ta không dùng thuật ngữ “tập hợp của tất cả các tập hợp” mà đề xuất một khái niệm tổng quát hơn là “lớp”. Trong đó, người ta chỉ cần khoanh vùng một tập hợp bao gồm đủ nhiều các tập hợp nào đó (nhưng không phải là tất cả) để làm việc thì sẽ không phải gặp mâu thuẫn nữa. Nghịch lý này thúc đẩy Ernst Zermelo phát triển lý thuyết tập hợp tiên đề ngày nay trở thành lý thuyết tập hợp Zermelo – Fraenkel.
NOP là một chỉ thị máy tính không làm gì khác ngoài việc tăng giá trị cho bộ đếm chương trình. Không có thành tố nào khác của trạng thái bộ xử lý bị thay đổi. Tất nhiên, các thanh ghi mà người dùng có thể nhìn thấy sẽ không bị thay đổi, nhưng trạng thái bộ xử lý và mã điều kiện không bị thay đổi.
NOP dùng để làm gì
Câu hỏi là tại sao ta cần có NOP trong khi đã có chỉ thị HLT (halt: dừng hoạt động) hoặc RST (reset: khởi động lại). Và tại sao lại là NOP? Nó cần thiết cho ai?
Câu trả lời là chỉ thị NOP thường được sử dụng để gỡ lỗi và cập nhật chương trình ở dạng mã máy. Nếu sau khi lập trình xong mà ta bỗng muốn viết thêm một số dòng vào đó thì chỉ cần viết đè những chỉ thị mới lên những vị trí đã có dành chỗ sẵn bằng các chỉ thị NOP. Ngoài ra, các chỉ thị bị lỗi hay viết không chính xác sẽ có thể được thay thế chỉ đơn giản là bằng cách ghi đè các chỉ thị NOP tiếp theo lên chính các chỗ viết sai đó. Nếu không dành chỗ sẵn như thế, ta sẽ phải chèn các dòng chỉ thị mới và việc chèn có nghĩa là có thể gây xáo trộn nguy hại do sự dịch chuyển vị trí của chương trình cũ.
Chỉ thị NOP còn được dùng để bắt buộc bộ xử lý phải đợi một lát cho các thiết bị bên ngoài (thường làm việc chậm hơn) có thể kịp hoàn thành công việc vào/ra dữ liệu của chúng và chuyển kết quả cho bộ xử lý. Vậy là NOP cần thiết cho mục đích đồng bộ hóa các hoạt động.
NOP trong các ngôn ngữ khác nhau
Thời đại của các bộ vi điều khiển 8-bit đến vào cuối những năm 1970, và NOP là một chỉ thị có thể được sử dụng theo nhiều cách. Đầu tiên, nó được sử dụng để vá mã. Thời đó bộ nhớ đắt gấp hàng nghìn lần so với hiện nay. Bộ nhớ flash chưa ra đời và ta buộc phải sử dụng các vi mạch ROM lập trình bằng mặt nạ. Hơn nữa, hầu như tất cả các công cụ phát triển phổ biến ngày nay thì thời ấy đều chưa tồn tại bởi vì PC và máy trạm vẫn chưa xuất hiện.
Ví dụ trong ngôn ngữ lập trình C, một dấu chấm phẩy (;) hoặc một khối trống ({}) là một NOP.
Với jQuery, hàm "jQuery.noop ()" tạo ra một NOP.
Trong Perl, câu chỉ thị dấu chấm lửng (…) có thể được sử dụng như một NOP. Tuy nhiên, nếu Perl cố gắng thực thi mã, nó sẽ đưa ra một ngoại lệ Unimplemented.
Trong Python, câu chỉ thị "pass" có thể được sử dụng như một NOP.
Với Visual Basic, dấu chấm phẩy (;) là NOP.
[1] Bertrand Arthur William Russell (18/05/1872 – 02/02/1970) là nhà triết học, toán học, logic học và sử học người Anh. Ông nhận được giải Nobel Văn học năm 1950. “Nghịch lý thợ cạo” minh họa trong lý thuyết tập hợp: nếu S chứa chính nó thì theo định nghĩa của S, tập S không phải là một phần tử của S. Nếu S không chứa chính nó thì cũng do định nghĩa của S chính S lại là một phần tử của S. Các mệnh đề “S là một phần tử của S” và “S không là phần tử của S” cả hai không thể cùng xảy ra. Russell không đưa ra một câu trả lời rõ ràng tuy nhiên ông có nêu cách giải quyết bằng thuyết hình thái (type theory). Ông cho rằng chính sự luẩn quẩn của logic ngôn ngữ đã tạo nên nghịch lý này. Tất cả các đối tượng khả thể đều phải được khu biệt theo theo hình thái của chúng và vì vậy cần phải có một hệ thống phân cấp hình thái (hierarchy). Trong đó đối tượng khả thể (sự vật, hiện tượng, khái niệm) là một loại hình thái. Thuộc tính của các đối tượng, thuộc tính của thuộc tính đối tượng là những loại hình thái riêng biệt và độc lập. Russell cho rằng về nguyên tắc không được gán ghép một thuộc tính bao hàm thuộc tính có sẵn như là một thuộc tính của chính đối tượng, nghĩa là không thể đưa ra một vấn đề mà tự nó đã tồn tại trong nó.