2009-03-20 52 views
85

Tôi đang chuẩn bị một số tài liệu đào tạo trong C và tôi muốn các ví dụ của mình phù hợp với mô hình ngăn xếp điển hình.Hướng phát triển ngăn xếp trong hầu hết các hệ thống hiện đại là gì?

Ngăn hướng C phát triển trong Linux, Windows, Mac OSX (PPC và x86), Solaris và Unix gần đây nhất là gì?

+1

Phiên bản hướng xuống dưới: http://stackoverflow.com/questions/2035568/why-do-stacks-typically-grow-downwards –

Trả lời

126

tăng trưởng stack thường không phụ thuộc vào hệ điều hành riêng của mình, nhưng trên bộ vi xử lý nó đang chạy trên. Solaris, ví dụ, chạy trên x86 và SPARC. Mac OSX (như bạn đã đề cập) chạy trên PPC và x86. Linux chạy trên tất cả mọi thứ từ danh dự lớn của tôi 'Hệ thống z tại nơi làm việc đến puny little wristwatch.

Nếu CPU cung cấp bất kỳ loại lựa chọn nào, quy ước ABI/gọi được hệ điều hành sử dụng chỉ định lựa chọn nào bạn cần thực hiện nếu bạn muốn mã của bạn gọi mã của người khác.

Các bộ vi xử lý và chỉ đạo của họ là:

x86   down 
SPARC  selectable. The standard ABI uses down. 
PPC   down, I think. 
System z  in a linked list, I kid you not. 
      (but still down, at least for zLinux). 
ARM   selectable, but Thumb2 has compact encodings only for down (LDMIA (increment after)/STMDB (decrement before)) 
Mostek6502 down (but only 256 bytes). 
RCA1802A  any way you want, subject to SCRT implementation. 
PDP11  down. 

Hiển thị tuổi của tôi trên những vài ngoái, 1802 là chip được sử dụng để kiểm soát các tàu con thoi sớm (cảm nếu những cánh cửa đã được mở, tôi nghi ngờ, dựa trên sức mạnh xử lý nó có :-) và máy tính thứ hai của tôi, COMX-35 (theo số ZX80) của tôi.


Chi tiết PDP11 được lấy từ here.

Kiến trúc SPARC sử dụng mô hình đăng ký cửa sổ trượt. Các chi tiết có thể nhìn thấy về mặt kiến ​​trúc cũng bao gồm một bộ đệm tròn của các cửa sổ đăng ký có giá trị và được lưu trong bộ nhớ cache nội bộ, với các bẫy khi quá/lưu lượng. Xem here để biết chi tiết. Như hướng dẫn the SPARCv8 manual explains, SAVE và RESTORE giống như hướng dẫn ADD cộng với xoay vòng sổ đăng ký. Sử dụng một hằng số dương thay vì tiêu cực thông thường sẽ tạo ra một chồng tăng lên.


Kỹ thuật SCRT nói trên là một kỹ thuật khác - 1802 đã sử dụng một số hoặc 16 đăng ký 16 bit cho SCRT (kỹ thuật gọi và trả lại chuẩn). Một là bộ đếm chương trình, bạn có thể sử dụng bất kỳ thanh ghi nào như PC với lệnh SEP Rn. Một là con trỏ ngăn xếp và hai được thiết lập luôn luôn trỏ đến địa chỉ mã SCRT, một cho cuộc gọi, một cho trả lại. Không đăng ký được xử lý theo cách đặc biệt. Hãy ghi nhớ những chi tiết này là từ bộ nhớ, chúng có thể không hoàn toàn chính xác. Ví dụ, nếu R3 là PC, R4 là địa chỉ cuộc gọi SCRT, R5 là địa chỉ trả về SCRT và R2 là "stack" (dấu ngoặc kép khi nó được thực hiện trong phần mềm), SEP R4 sẽ đặt R4 là PC và bắt đầu chạy mã cuộc gọi SCRT.

Nó sẽ sau đó cửa hàng R3 trên R2 "ngăn xếp" (Tôi nghĩ R6 đã được sử dụng để lưu trữ tạm thời), điều chỉnh nó lên hoặc xuống, lấy hai byte sau R3, tải chúng vào R3, sau đó làm SEP R3 và đang chạy tại địa chỉ mới.

Để trả lại, nó sẽ SEP R5 sẽ kéo địa chỉ cũ ra khỏi ngăn xếp R2, thêm hai vào nó (để bỏ qua byte địa chỉ của cuộc gọi), tải nó vào R3 và SEP R3 để bắt đầu chạy mã trước đó.

Rất khó khăn để quấn đầu của bạn xung quanh ban đầu sau khi tất cả mã dựa trên ngăn xếp 6502/6809/z80 nhưng vẫn thanh lịch theo kiểu sắp xếp ngang hàng. Ngoài ra một trong những tính năng bán hàng lớn của chip là 16 thanh ghi 16-bit, và bạn ngay lập tức mất 7 trong số đó (5 cho SCRT, hai cho DMA và ngắt từ bộ nhớ). Ahh, chiến thắng của tiếp thị trên thực tế.

Hệ thống z thực sự khá giống nhau, sử dụng thanh ghi R14 và R15 để gọi/trả lại.

+3

Để thêm vào danh sách, ARM có thể phát triển theo một trong hai hướng, nhưng có thể được đặt thành cái này hay cái khác bằng cách thực hiện silic cụ thể (hoặc có thể được lựa chọn bởi phần mềm). Vài người tôi đã xử lý luôn ở chế độ phát triển. –

+0

Chà, đây là điều mặc khải - Tôi đã luôn luôn giả định rằng nó đã giảm cho mọi kiến ​​trúc. Danh sách được liên kết! –

+0

Tôi nghĩ rằng PPC có thể lựa chọn, nhưng nó phát triển trên OS X (kể từ khi 68k mà Mac chạy trên trước khi có một ngăn xếp xuống.) – Michael

4

stack mọc xuống trên x86 (được xác định bởi các kiến ​​trúc, gia tăng pop chồng con trỏ, đẩy suất này.)

2

Nó phát triển vì bộ nhớ được cấp cho chương trình có "dữ liệu cố định" tức là mã cho chính chương trình ở dưới cùng, sau đó là vùng đệm ở giữa. Bạn cần một điểm cố định khác để tham chiếu ngăn xếp, để bạn rời khỏi đầu trang. Điều này có nghĩa là ngăn xếp phát triển, cho đến khi nó có khả năng tiếp giáp với các đối tượng trên heap.

21

Trong C++ (thích nghi với C) stack.cc:

static int 
find_stack_direction() 
{ 
    static char *addr = 0; 
    auto char dummy; 
    if (addr == 0) 
    { 
     addr = &dummy; 
     return find_stack_direction(); 
    } 
    else 
    { 
     return ((&dummy > addr) ? 1 : -1); 
    } 
} 
+11

Ồ, đã lâu rồi tôi mới thấy từ khóa "tự động". – paxdiablo

+4

(& dummy> addr) không xác định. Kết quả của việc đưa hai con trỏ tới một toán tử quan hệ được định nghĩa chỉ khi hai con trỏ trỏ vào cùng một mảng hoặc cấu trúc. – sigjuice

+1

Đang cố gắng điều tra bố cục ngăn xếp của riêng bạn - một thứ mà C/C++ không chỉ định - là "không thể chuyển đổi" để bắt đầu, vì vậy tôi sẽ không thực sự quan tâm đến điều đó. Dường như chức năng này sẽ chỉ hoạt động chính xác một lần. – ephemient

6

Ưu điểm của việc phát triển xuống là trong các hệ thống cũ chồng là thường ở phía trên cùng của bộ nhớ. Chương trình thường đầy bộ nhớ bắt đầu từ phía dưới, do đó loại quản lý bộ nhớ này giảm thiểu sự cần thiết phải đo lường và đặt dưới cùng của ngăn xếp một nơi nào đó hợp lý.

+0

Không phải là 'lợi thế', tautology thực sự. – EJP

3

Trong MIPS, không có hướng dẫn push/pop. Tất cả push/pops được thực hiện một cách rõ ràng bằng cách tải/lưu trữ tương đối với con trỏ ngăn xếp và sau đó điều chỉnh bằng tay con trỏ $sp. Tuy nhiên, tất cả các thanh ghi (trừ $0) đều là mục đích chung, theo lý thuyết bất kỳ đăng ký nào có thể là con trỏ ngăn xếp và ngăn xếp có thể phát triển theo bất kỳ hướng nào mà người lập trình muốn. MIPS ABI thường phát triển xuống dưới.

Trong Intel 8051 ngăn xếp lớn lên, có thể do không gian bộ nhớ quá nhỏ (128 byte trong phiên bản gốc) không có đống và bạn không cần đặt chồng lên trên để nó được tách ra từ đống phát triển từ phía dưới.

3

Trên hầu hết các hệ thống, ngăn xếp phát triển và bài viết của tôi tại số https://gist.github.com/cpq/8598782 giải thích TẠI SAO nó phát triển. Lý do là đó là bố trí tối ưu của hai vùng bộ nhớ đang phát triển (đống và ngăn xếp).

+0

mà gist dường như đã chết: ( – Ven

+1

@Ven, tôi đã sửa liên kết – valenok

Các vấn đề liên quan