Cuộc gọi ngăn xếp bắt đầu ở dưới cùng hoặc trên cùng?


10

Một chồng là một cái gì đó chồng chất từ ​​dưới lên.

Do đó, ngăn xếp cuộc gọi thêm các mục mới trên ngăn xếp khi các chức năng được gọi với các mục được xóa khỏi ngăn xếp khi mỗi chức năng kết thúc cho đến khi ngăn xếp trống và sau đó chương trình kết thúc.

Nếu những điều trên là chính xác, tại sao mọi người lại đề cập đến việc điều khiển di chuyển "lên" ngăn xếp cuộc gọi? Chắc chắn điều khiển di chuyển xuống ngăn xếp cuộc gọi cho đến khi nó chạm đến đáy.


Khi một chức năng được gọi, một mục được thêm vào đầu ngăn xếp và điều khiển được chuyển đến chức năng đó. Do đó, điều khiển di chuyển từ mục bên dưới trong ngăn xếp sang mục trên cùng của nó - hướng lên.
treecoder

1
@greengit: biểu thức "lên ngăn xếp cuộc gọi" được sử dụng với các ngoại lệ, trong đó điều khiển thực sự di chuyển theo cách ngược lại.
Michael Borgwardt

@MichaelBorgwardt: Bạn đúng.
treecoder

1
@MichaelBorgwardt: Tôi đã thấy biểu thức "lỗi di chuyển lên ngăn xếp cuộc gọi". Chắc chắn đó là không chính xác.
CJ7

Câu trả lời:


8

Có hai lý do có thể cho việc sử dụng này:

  • Trong ngữ cảnh của các trường hợp ngoại lệ, điều khiển chuyển sang chức năng / phương thức gọi và hệ thống phân cấp cuộc gọi này thường được hiển thị bằng phương thức chính ở trên và các lệnh gọi phương thức tạo thành một hệ thống phân cấp xuống dưới, với mức độ trừu tượng giảm dần. Trong hệ thống phân cấp này, một ngoại lệ di chuyển lên trên.

  • Ngăn xếp chương trình thực tế trong một ứng dụng x86 bình thường được đảo ngược, tức là nó phát triển xuống dưới. Các hướng dẫn mã máy PUSH / PUSHW / PUSHD làm giảm con trỏ ngăn xếp. Các kiến ​​trúc khác có thể chia sẻ mô hình này.


Không phải ý tưởng từ trên xuống trái với khái niệm hàng ngày về một "chồng" là một đống vật phẩm bắt đầu từ phía dưới sao?
CJ7

@CraigJ: thực tế là các bit của mỗi byte trong nội dung của ngăn xếp sẽ được lưu trữ vật lý trong các chip riêng biệt. Ai quan tâm?
Michael Borgwardt

1

Tất cả phụ thuộc vào định nghĩa của từ; chính xác ý bạn là gì với các từ "trên cùng" và "dưới cùng" trong ngữ cảnh này, và cả về việc triển khai hệ điều hành hoặc kiến ​​trúc máy tính.

Tôi nhớ những điều sau đây từ lâu, khi tôi đang lập trình trên Commodore 64. Bộ nhớ giữa địa chỉ $ 0800 (2048) và $ 9FFF (40959) được dành riêng cho các chương trình BASIC. Mã của chương trình BASIC của bạn được lưu trữ bắt đầu từ địa chỉ thấp hơn ($ 0800, tăng dần từ đó). Ngăn xếp, để lưu trữ các biến và trả về địa chỉ của các chương trình con, bắt đầu ở đầu ($ 9FFF) của phạm vi đó và phát triển theo các địa chỉ thấp hơn. Vì vậy, trong bối cảnh này, thật hợp lý khi thấy ngăn xếp ngày càng đi xuống và khi bạn trở về từ một chương trình con, khung ngăn xếp của chương trình con đã bị loại bỏ bằng cách tăng con trỏ ngăn xếp, để bạn có thể nói rằng bạn đang "di chuyển lên ngăn xếp" khi trở về từ một chương trình con.

Tôi không biết nó hoạt động như thế nào trên các phiên bản hiện đại của bộ xử lý Windows hoặc Intel x86. Có thể ngăn xếp hoạt động theo cách khác, tức là nó phát triển từ địa chỉ thấp hơn đến địa chỉ cao hơn. Nếu đó là trường hợp thì có lẽ bạn sẽ sử dụng các từ "trên cùng", "dưới cùng" và "lên", "xuống" chính xác theo cách khác.


0

Để gọi một hàm như foo (6, x + 1) ...

  1. Đánh giá các biểu thức tham số thực tế, chẳng hạn như x + 1, trong ngữ cảnh của trình gọi.
  2. Phân bổ bộ nhớ cho người địa phương của foo () bằng cách đẩy một "khối cục bộ" bộ nhớ phù hợp vào "ngăn xếp cuộc gọi" dành riêng cho mục đích này. Đối với các tham số nhưng không phải là biến cục bộ, lưu trữ các giá trị từ bước (1) vào vị trí thích hợp trong khối cục bộ của foo ().
  3. Lưu trữ địa chỉ thực hiện hiện tại của người gọi ("địa chỉ trả về") và chuyển thực hiện sang foo ().
  4. foo () thực thi với khối cục bộ của nó có sẵn một cách thuận tiện ở cuối ngăn xếp cuộc gọi.
  5. Khi foo () kết thúc, nó thoát ra bằng cách bật các địa phương của nó ra khỏi ngăn xếp và "trả về" cho người gọi bằng cách sử dụng địa chỉ trả lại được lưu trước đó. Bây giờ, người gọi địa phương đang ở cuối ngăn xếp và nó có thể tiếp tục thực thi.

Tài liệu tham khảo:

http : // csl Library.stanford.edu/102/PointersAndMemory.pdf (p15)


Lưu ý rằng điều này rất cụ thể cho quy ước gọi. Có các quy ước gọi cho phép người gọi dọn dẹp, hầu hết sử dụng ít nhất một số thanh ghi, v.v.

0

Nếu bạn khái niệm một ngăn xếp như một thứ từ dưới lên, giống như một hình trụ có các quả bóng tennis trong đó trong thực tế hấp dẫn bình thường, thì điều khiển sẽ di chuyển lên ngăn xếp khi các hàm được gọi. Khi các chức năng hoàn thành, điều khiển di chuyển xuống ngăn xếp.

Nếu bạn khái niệm một ngăn xếp như một vật từ trên xuống, giống như một khối bóng tennis giống nhau nhưng có trọng lực ngược, thì điều khiển di chuyển xuống ngăn xếp khi các chức năng được gọi và lên ngăn xếp khi các chức năng hoàn thành.

Cả hai chỉ là mô hình trong đầu của bạn và về cơ bản là hoàn toàn tùy ý. Bạn có thể khái niệm nó như một điều phụ nếu bạn thích, nhưng có thể gặp khó khăn khi giao tiếp với mọi người. Cá nhân tôi nghĩ rằng nếu A gọi B và B gọi C thì C là đáy của ngăn xếp (thực tế hấp dẫn đảo ngược) và nếu một ngoại lệ xảy ra trong C, bạn muốn bong bóng ngoại lệ đó lên "A. Tôi nghĩ rằng đây có thể là sử dụng ngôn ngữ phổ biến hơn vì cảm giác là C nằm sâu và A là đỉnh. Chức năng đầu tiên trực quan hơn đối với tôi và các chức năng trở nên sâu hơn trên mỗi cuộc gọi.

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.