Tôi đã biết về hướng dẫn jmp trong một thời gian, nhưng nó không bao giờ đánh tôi như là thậm chí từ xa không an toàn. Gần đây tôi đã có nguyên nhân để kiểm tra thông số kỹ thuật CIL và was very surprised to discover jmp is considered unverifiable.Tại sao lệnh jmp của CLR không thể xác minh?
Trả lời
Bởi vì, không giống như một call
, callvirt
, hoặc calli
, nơi stack frame của người gọi sẽ vẫn còn trên ngăn xếp để được nhìn thấy bởi stackwalks an ninh truy xuất mã lệnh tương lai kích hoạt (có lẽ gián tiếp) bởi callee, một hướng dẫn jmp
nước mắt xuống người gọi stack frame trước khi chuyển vào callee và do đó vô hình đối với bất kỳ stackwalks CAS nào mà callee có thể kích hoạt.
Chỉnh sửa: Tôi nghĩ naasking là đúng về câu trả lời ở trên là sai. Tôi bây giờ nghĩ rằng sự khác biệt giữa (có thể xác minh) đuôi.call trình tự và (unverifiable) jmp trình tự có thể là một cuộc gọi đuôi yêu cầu đẩy các đối số cho cuộc gọi vào ngăn xếp đánh giá, nơi họ có thể được xác minh theo cách bình thường, trong khi jmp
yêu cầu ngăn xếp đánh giá trống và khiến cho jump-ee kế thừa các đối số của bước nhảy. Có lẽ không có lý do gì để làm phức tạp người xác minh kiểm tra các hướng dẫn jmp
nhưng có thể làm như vậy trong các điều kiện tương tự với các yêu cầu trên các chuỗi tail.call
(một trong số đó là người gọi và callee phải ở trong cùng một assembly). ra khỏi CAS của tôi đoán ở trên, ít nhất là lên đến rõ ràng .Deny()
cuộc gọi).
Nếu vậy, đây sẽ là một phần liên quan của spec: (phân vùng III, Mục 3,37)
Những lập luận hiện đang chuyển với phương pháp đích.
Ngăn xếp đánh giá phải trống khi lệnh này được thực thi. Công ước gọi, số và loại đối số tại địa chỉ đích phải khớp với quy tắc hiện tại.
Trong khi hợp lý lúc đầu đỏ mặt, điều này không đứng lên để giám sát kỹ hơn. Các .tailcall tiền tố có hành vi gần giống nhau, mặc dù tổng quát hơn, nhưng .tailcall là kiểm chứng. Tài liệu chỉ đơn giản tuyên bố rằng .tailcall được bỏ qua khi gọi từ mã không đáng tin cậy đến đáng tin cậy. Nếu đây là lý do jmp là unverifiable, tôi không thấy lý do tại sao họ sẽ không chỉ sử dụng cùng một hành vi cho jmp. – naasking
Điểm rất tốt, cảm ơn naasking. –
Tôi nghĩ "Rodrigo Kumpera" đã đăng trên trang blog được liên kết có quyền: nếu có đối số là by-ref, thì bạn có thể lưu trữ tham chiếu đến một địa phương rồi thực hiện một jmp. Một phân tích dòng chảy kiểm soát được yêu cầu để đảm bảo điều này không xảy ra, mặc dù một tương đối đơn giản. Tôi muốn đặt cược họ chỉ không muốn bận tâm kể từ khi jmp được thêm chủ yếu để hỗ trợ C + +. Mối nguy hiểm tương tự tồn tại đối với .tailcall, vì vậy tôi không chắc chắn cách xử lý đó, nghĩa là. không thể xác minh hoặc .tailcall bị bỏ qua. Tôi sẽ phải kiểm tra nó tại một số điểm. – naasking
- 1. Tại sao điều này. Net IL không thể xác minh?
- 2. Tại sao CLR lại ném ThreadAbortException?
- 3. Tại sao liên minh của tôi không hiển thị các giá trị chính xác?
- 4. Cách xác minh bản sao làm việc của Subversion
- 5. Tại sao tôi không thể nhập loại C# của mình vào IronPython?
- 6. Xác minh Mockito Không Failing
- 7. Có lệnh dòng lệnh để xác minh phiên bản .NET nào đã được cài đặt không.
- 8. Tại sao cron không thực thi tập lệnh PHP của tôi một cách chính xác?
- 9. Tại sao có rất nhiều $ NẾU được xác định (CLR) trong VCL/RTL?
- 10. Tại sao dòng lệnh của tôi không chạy từ cron?
- 11. Tại sao tập lệnh Perl của tôi không thể thấy các biến() mà tôi đã xác định trong tệp khác?
- 12. Tại sao lệnh gọi Canvas.drawText() của tôi không hoạt động
- 13. Tại sao mã xác nhận (xác thực MS) của tôi không thành công?
- 14. Tại sao nó không thể bắt MissingMethodException?
- 15. Hướng dẫn JMP - Mã Hex
- 16. Tại sao chiều dài của giây không chính xác?
- 17. Xcode không thể xác minh danh tính của máy chủ "github.com", Xcode
- 18. Tại sao liên minh không thể được sử dụng trong Thừa kế?
- 19. Nơi để xác minh ủy quyền cho một Lệnh?
- 20. Ứng dụng không thể xác minh mã số
- 21. Tại sao biểu thức CASE của tôi không xác định?
- 22. Cách xác minh xem tệp có tồn tại với tập lệnh VB
- 23. Loại chứng minh thể hiện của gia đình có thể được chứng minh không?
- 24. CLR của F # và C# giống nhau tại sao F # nhanh hơn C#
- 25. OTA - myApp không thể được cài đặt tại thời điểm này - Không thể xác minh thực thi
- 26. Tại sao một con trỏ thông minh không thể gọi hàm new() cho tôi trong hàm tạo của nó?
- 27. Tại sao tôi không thể thay đổi khung của UILabel?
- 28. MC3074 - loại không tồn tại trong "clr-namespace ..."
- 29. Tại sao tập lệnh Perl của tôi thoát với 137?
- 30. Tại sao tôi nhận được xác nhận của lệnh malloc C?
Điều này có thể bởi vì nó không thể xác minh tác động của thực hiện các phần khối mã hiện sau đó và khâu chặt vào khối mã điểm đến ... Something về ngăn xếp/theo dõi đống dường như cờ trong dreamworld nhỏ của tôi .. không phải là tôi biết điều này chắc chắn mặc dù ... tuy nhiên đó là ngay lập tức bù đắp bởi các thông tin ở đây ... http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.jmp .aspx ... trong đó nêu rõ rằng không có thông tin ngăn xếp nào được theo dõi/chuyển. Có thể có thứ gì đó bên dưới "giao diện người dùng" ở đây mà Microsoft đang ẩn. – War
Tôi không biết tại sao nó không thể xác minh được nhưng tôi có một thông tin thú vị. EQATEC Profiler của chúng tôi thu thập số liệu thống kê ẩn danh về tất cả các mã mà nó cấu hình (sử dụng EQATEC Analytics, btw). Bởi vì jmp phức tạp và không được xử lý tối ưu bởi profiler, chúng tôi quyết định theo dõi tần suất nó thực sự xảy ra. Chúng tôi hiện có 2 năm dữ liệu, thu thập từ hơn 1 triệu hội đồng định hình, tổng cộng 20 tỷ chỉ dẫn CIL. Khá nhiều. Và bao nhiêu là jmp? Không ai! Có, một jmp chưa bao giờ xảy ra trong bất kỳ ứng dụng của người dùng của chúng tôi (NETCF, SL, WP7, F # vv). Khá bất ngờ. –
Tôi không quá ngạc nhiên. Không có trình biên dịch tôi biết ngoại trừ có lẽ quản lý C + + phát ra lệnh jmp, bởi vì nó không thể xác minh. Bất kỳ việc sử dụng jmp nào cũng có thể được gửi đi trong các thư viện lớp đáng tin cậy. – naasking