Tại sao ngăn xếp phát triển xuống?


31

Tôi cho rằng có một lịch sử với nó, nhưng tại sao ngăn xếp lại phát triển xuống?

Đối với tôi, dường như tràn bộ đệm sẽ khó khai thác hơn rất nhiều nếu ngăn xếp tăng dần lên ...


3
stackoverflow.com/questions/1677415/ từ lưu ý rằng ngăn xếp có thể phát triển theo một mức độ nào đó.
JB King

6
Có một câu hỏi giống như câu hỏi này: stackoverflow.com/questions/2035568/ cấp . Vấn đề thực tế là có một câu hỏi và câu trả lời tốt hơn về vấn đề này ở đây: stackoverflow.com/questions/664744/
Kẻ

Câu hỏi được liên kết không bao gồm vấn đề tràn bộ đệm.
deadalnix

1
bởi vì đống lớn lên
tylerl

2
Là vị trí bộ nhớ 0 ở trên cùng hoặc dưới cùng?

Câu trả lời:


21

Tôi tin rằng nó xuất phát từ những ngày đầu của máy tính, khi bộ nhớ rất hạn chế và việc phân bổ trước một khối lớn bộ nhớ để sử dụng riêng cho ngăn xếp. Vì vậy, bằng cách phân bổ bộ nhớ heap từ địa chỉ 0 trở lên và ngăn xếp bộ nhớ từ cuối bộ nhớ trở xuống, bạn có thể có cả heap và stack chia sẻ cùng một vùng nhớ.

Nếu bạn cần thêm một chút nữa, bạn có thể cẩn thận với việc sử dụng ngăn xếp của mình; nếu bạn cần thêm stack, bạn có thể cố gắng giải phóng bộ nhớ heap. Tất nhiên, kết quả là, hầu hết, các sự cố ngoạn mục, vì ngăn xếp đôi khi sẽ ghi đè lên đống và ngược lại.

Quay lại những ngày đó không có sự đan xen, vì vậy không có vấn đề khai thác tràn bộ đệm. (Hoặc ít nhất là trong phạm vi mà interwebz tồn tại, tất cả đều nằm trong các cơ sở bảo mật cao của bộ quốc phòng thống nhất, vì vậy khả năng dữ liệu độc hại không cần phải suy nghĩ nhiều.)

Sau đó, với hầu hết các kiến ​​trúc, tất cả chỉ là vấn đề duy trì khả năng tương thích với các phiên bản trước đó của cùng một kiến ​​trúc. Đó là lý do tại sao các ngăn xếp lộn ngược vẫn còn với chúng ta ngày hôm nay.


8
Quay trở lại xa hơn trong lịch sử và không có heap, ngay cả ngày nay, nhiều bộ điều khiển vi mô 8 và 16 bit không có một đống. Ngăn xếp phát triển xuống để chương trình có thể được cài đặt trong một địa chỉ bộ nhớ thấp và ngăn xếp là bộ nhớ còn lại. Khởi tạo ngăn xếp có thể được thực hiện trước khi tải chương trình, đơn giản hóa các chương trình.
mattnz

1
Hầu hết các vi điều khiển nhỏ có một đống, chỉ không phải là một đống mà phát triển. Thật khó để biện minh cho việc sử dụng phân bổ bộ nhớ động trên heap khi bạn có lượng RAM nhỏ (<1Kbyte) để làm việc. Thông thường kích thước của phần bộ nhớ duy nhất thay đổi là ngăn xếp.
tehnyit

7

bộ nhớ chương trình được thiết lập theo truyền thống là

code
constants
heap (growing up)
...
stack (growing down)

đống và ngăn xếp có thể được trao đổi

nhưng tràn bộ đệm vẫn có thể được khai thác nếu ngăn xếp đi theo cách khác

lấy kinh điển strcpylàm ví dụ

foo(char* in){
char[100] buff;
strcpy(buff,in);
}

với bộ nhớ ngăn xếp như

ret foo
arg in
buff array
ret strcpy
buf pointer
in

điều này có nghĩa là khi sao chép xong, địa chỉ trả về strcpynằm sau bộ đệm (thay vì foođịa chỉ trả về) và có thể được ghi đè bằng bất cứ thứ gì có trongin


4

Một số phần cứng có heap bắt đầu từ bộ nhớ cao, phát triển xuống, trong khi ngăn xếp bắt đầu ở bộ nhớ thấp tăng lên.

Phần cứng PA-RISC của HP, trong số những người khác, thực hiện việc này: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php

Hệ điều hành Multics đáng kính chạy trên phần cứng có (một trong số rất nhiều) ngăn xếp đang phát triển: xem http://www.acsac.org/2002/ con / classic-multics.pdf, cuối phần 2.3.2:

Thứ ba, các ngăn xếp trên bộ xử lý Multics phát triển theo hướng tích cực, thay vì theo hướng tiêu cực. Điều này có nghĩa là nếu bạn thực sự hoàn thành tràn bộ đệm, bạn sẽ ghi đè lên các khung ngăn xếp không sử dụng, thay vì con trỏ trở lại của riêng bạn, khiến việc khai thác trở nên khó khăn hơn nhiều.

Đó là một tuyên bố khá thú vị. Có phải lỗi tràn bộ đệm đã trở thành một vấn đề lớn như vậy chỉ vì sự sắp xếp thủ tục "cuộc gọi-ngăn xếp-khung" thông thường? Ngoài ra, bao nhiêu danh tiếng của Multics như Totally Invulnerable chỉ là một phần nhỏ của thiết kế phần cứng?


Chà, việc không có (các) ngăn xếp thực thi có lẽ đã giúp Multics nhiều như hướng ngăn xếp thông minh, và tất nhiên với nhiều chương trình được viết bằng PL / 1, tràn chuỗi cũng không thực sự là vấn đề.
Greg A. Woods
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.