Giải thích về ghi chú 2: Trong hình minh họa ta sẽ thấy Stack nằm lộn ngược từ trên xuống, đó cũng là cách bộ nhớ Stack được tổ chức trong thực tế, nhờ phát triển từ địa chỉ cao xuống địa chỉ thấp mà CPU có thể phát hiện ra lỗi Stack overflow một cách dễ dàng (so sánh với 0).
Để hiểu vì sao khi phát triển từ bộ nhớ cao xuống bộ nhớ thấp thì phát hiện lỗi stack overflow dễ dàng hơn, ta cần điểm qua vài ý sau:
Các bộ xử lý luôn có một cơ chế đặc biệt với giá trị 0, nhờ đó khi xảy tràn số khi cộng hoặc trừ, thường sẽ có các cờ hoặc exception tự động phát ra. Do vậy sẽ dễ dàng và nhanh hơn để kiểm tra xem phép toán vừa làm có bị tràn số hay không.
Ví dụ:
Đoạn lệnh:
x = a – b, nếu cờ CF bật thì nhảy đến L sẽ nhanh hơn:
Nếu a < b thì nhảy đến L, ngược lại thực hiện x = a – b.Vì vậy:if PUSH x, kiểm tra CF bật thì lỗi sẽ nhanh hơn là:if sizeof(x) + SP > (stack_size) thì bị lỗi, else PUSH x.
Nếu vẫn chưa hiểu khúc này thì bạn có thể xem một ví dụ khi ta duyệt qua các phần tử mảng trong ngôn ngữ bậc cao:
Trong hai ví dụ vừa viết thì [A] sẽ chạy nhanh hơn [B], nguyên nhân vì vòng while bên trên được so sánh với 0, ta chỉ phải đọc biến x trong bộ nhớ, và có các lệnh riêng để làm việc, còn trong ví dụ [B] ta so sánh với my_array.Length, vốn là phép tính so sánh 2 giá trị trong bộ nhớ, ta sẽ phải đọc thêm giá trị từ my_array.Length, rồi sau đó mới so sánh được.
Trước đây ta còn phải dùng các phân đoạn khác nhau cho code, data, stack… vì kích thước 1 phân đoạn nhỏ hơn kích thước bộ nhớ, và trong nhiều trường hợp cũng nhỏ hơn kích thước mà chương trình cần nên stack thường được để riêng ra một đoạn. Do vậy khi cần cấp 1 stack 16KB cho một chương trình, HĐH sẽ cấp riêng cho nó 1 đoạn và đặt thanh ghi SP lên trên đỉnh cao nhất của đoạn được cấp (16KB), tức là chỉ vào đáy stack – vì nó lộn ngược. Sau đó ứng dụng đó cứ việc sử dụng thoải mái, nhưng chỉ cần đẩy dữ liệu vào mà tràn ra, tức SP vì giảm xuống âm thì HĐH sẽ phát hiện lỗi.Đây là một trong những lý do ảnh hưởng đến lựa chọn cho việc để stack nằm lộn ngược. Nhưng hiện tại các lý do này có lẽ không còn phù hợp, vì kích thước các phân đoạn đã rất lớn, và tất cả các phần của chương trình dư sức nằm chung 1 đoạn. Bản thân stack cũng sẽ được để đâu đó phía sau code và data nên chẳng bao giờ còn gặp lỗi tràn số, vì trước khi stack chỉ được về tới 0 thì nó đã đè lên các các phần khác của chương trình. Chế độ bảo vệ bộ nhớ cũng sẽ được dùng thay thế cho chế độ kiểm tra tràn số…Như trong bài viết gốc có nói, việc dễ phát hiện lỗi cũng chỉ là một trong những lý do cho sự lựa chọn này, và có lẽ cũng không phải là lý do quan trọng nhất.