2009-05-15 29 views
7

Tôi có một số mã cũ được viết bằng C cho 16 bit sử dụng Borland C++ chuyển đổi giữa nhiều ngăn xếp, bằng cách sử dụng longjmps. Nó tạo ra một ngăn xếp mới bằng cách thực hiện một malloc, và sau đó thiết lập SS và SP đăng ký cho phân khúc và bù đắp, resp., Của địa chỉ của khu vực malloc'd, sử dụng Assembler nội tuyến. Tôi muốn chuyển đổi nó sang Win32, và có vẻ như hai hướng dẫn nên được thay thế bằng một thiết lập duy nhất ESP. Hai hướng dẫn được bao quanh bởi một cặp CLI/STI, nhưng trong Win32 chúng đưa ra "hướng dẫn đặc quyền", vì vậy tôi đã cắt chúng ra ngay bây giờ. Tôi thực sự vô tội khi nói đến Windows, vì vậy, tôi khá ngạc nhiên khi trường hợp thử nghiệm đầu tiên của tôi hoạt động! Vì vậy, câu hỏi khá mơ hồ của tôi là hỏi các chuyên gia ở đây nếu những gì tôi đang làm là a) quá nguy hiểm để tiếp tục, hoặc b) sẽ hoạt động nếu tôi thêm một số mã, có biện pháp phòng ngừa nhất định, vv? Nếu sau này, những gì cần được thêm vào, và nơi tôi có thể tìm hiểu về nó? Tôi có phải lo lắng về bất kỳ thanh ghi nào khác, như SS, EBX, v.v. không? Tôi đang sử dụng không tối ưu hóa ... Cảm ơn mọi lời khuyên mọi người có thể cho tôi.Chuyển đổi ngăn xếp trong C++

+1

Ồ, đó là một câu hỏi rất thú vị! Tôi không chính xác một chuyên nghiệp tại 16-bit C + + vì vậy tôi tự hỏi tại sao bạn trao đổi ngăn xếp ở tất cả? –

+1

Cho rằng đó là mã 16-bit cũ, tôi đoán rằng đó là một số loại thực hiện sợi homebrew. Tôi biết một vài trò chơi video điều khiển đã làm một cái gì đó như thế này bởi vì các chủ đề được cung cấp bởi hệ thống rất nặng. – Charlie

+0

Có, như một số các phản ứng xuất sắc được phát hiện, đó là (là) thực hiện sợi homebrew - triển khai đầu tiên của tôi về lập trình dựa trên luồng trên PC. Phiên bản 16-bit đã được sử dụng cho công việc sản xuất tại một công ty lớn ở Mỹ. Tôi đã không nhận ra rằng Win32 có một sợi thực hiện - Tôi sẽ đọc bài báo trích dẫn bởi Greg Hewgill. Cảm ơn tất cả các bạn! –

Trả lời

9

Xóa CLI/STI vẫn hoạt động do sự khác biệt trong môi trường hoạt động.

Trên DOS 16 bit, có thể xảy ra gián đoạn và gián đoạn này ban đầu sẽ chạy trên cùng một ngăn xếp. Nếu bạn đã bị gián đoạn ở giữa của hoạt động, ngắt có thể sụp đổ bởi vì bạn chỉ cập nhật ss và không sp.

Trên Windows và bất kỳ môi trường hiện đại nào khác, mỗi luồng chế độ người dùng sẽ có ngăn xếp riêng. Nếu chủ đề của bạn bị gián đoạn vì bất kỳ lý do gì, thì ngăn xếp và ngữ cảnh được lưu giữ an toàn - bạn không phải lo lắng về điều gì khác đang chạy trên luồng và ngăn xếp của bạn. cli/sti trong trường hợp này sẽ được bảo vệ chống lại một cái gì đó bạn đã được bảo vệ chống lại bởi hệ điều hành.

Như Greg đã đề cập, cách an toàn, được hỗ trợ trao đổi ngăn xếp như thế này trên Windows là CreateFiber/SwitchToFiber. Điều này không có tác dụng phụ của việc thay đổi toàn bộ bối cảnh của bạn, vì vậy nó không giống như chỉ chuyển đổi ngăn xếp.

Điều này thực sự đặt ra câu hỏi về những gì bạn muốn làm. Rất nhiều lần, chuyển đổi ngăn xếp là để có được bằng không gian ngăn xếp hạn chế, đó là 64k trên 16-bit DOS. Trên Windows, bạn có ngăn xếp 1 MB và bạn có thể phân bổ lớn hơn nữa. Tại sao bạn đang cố gắng chuyển đổi ngăn xếp?

+0

Đây là lần đầu tiên tôi thực hiện Lập trình dựa trên luồng trên PC. Tôi đã không nhận ra rằng Win32 có một sợi thực hiện, nhưng nó có thể là rất nhiều rắc rối để chuyển đổi mã của tôi để Fibers - Tôi chắc chắn sẽ đọc bài báo trích dẫn bởi Greg Hewgill, mặc dù. Cảm ơn tất cả các bạn! –

5

Đến nay cách an toàn nhất để thực hiện việc này là chuyển mã tới các cấu trúc đa lập trình Win32 chính thức, chẳng hạn như chủ đề hoặc sợi. Fibers cung cấp một mô hình đa ngăn xếp rất nhẹ có vẻ thích hợp cho ứng dụng của bạn.

Bài viết Why does Win32 even have fibers? cũng là một điều thú vị.

+0

Một trong các bài viết trong bài viết đó nói rằng "họ sẽ chuyển đổi cơ sở ngăn xếp, nhưng không cập nhật giới hạn ngăn xếp. Hoặc không chuyển danh sách xử lý ngoại lệ. Hoặc quên đổi trạng thái FP." Giả sử sợi nhìn sau những thứ đó cho tôi, tôi có thể làm longjmps giữa sợi? Nếu tôi muốn tự chăm sóc bản thân, chúng phức tạp như thế nào, và tôi có thể tìm hiểu về chúng ở đâu? Cám ơn. –

+1

Tôi đã liên kết với tài liệu MSDN về các sợi trong câu trả lời của tôi. Có một tham chiếu đầy đủ chức năng ở đó, sẽ trả lời hầu hết các câu hỏi của bạn. Lưu ý rằng tôi không nghĩ rằng bạn nên cố gắng "longjmp giữa các sợi", nhưng thay vào đó sử dụng các chức năng chính thức như SwitchToFiber. –

+0

Cảm ơn, Greg. Các tài liệu hướng dẫn nhìn một chút offputting, nhưng tôi sẽ bắt đầu đào sâu vào nó. –

0

Tôi đã thực hiện việc này ở chế độ người dùng và dường như không có vấn đề gì. Bạn không cần cli/sti, các hướng dẫn này chỉ ngăn chặn các ngắt tại thời điểm đó trong mã, mà không cần thiết từ những thông tin giới hạn mà bạn đã nói với chúng tôi.

0

Hãy xem Mtasker bởi Bert Hubert. Nó thực hiện đa nhiệm hợp tác đơn giản, nó có thể dễ dàng cho bạn để sử dụng điều này để chuyển mã của bạn.

0

Đừng quên rằng các ngăn xếp nhảy sẽ sắp xếp bất kỳ đối số hoặc biến ngăn xếp nào.

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