2012-07-01 32 views
6

Tôi đang duyệt qua nguồn của các triển khai khác nhau setjmplongjmp và nhận thấy rằng không phải tất cả các thanh ghi CPU được lưu trong cấu trúc jmp_buf. Sau khi xem xét AMD64 ABI, tôi nhận thấy rằng chỉ những thanh ghi được lưu trữ bằng callee mới được lưu.Tại sao setjmp (3) không lưu tất cả các thanh ghi trên AMD64?

Tôi không hiểu cách trạng thái chức năng có thể được tiếp tục hoàn toàn khi chỉ một số thanh ghi đã được lưu. Chắc chắn các thanh ghi chưa được lưu lại phải được ghi đè nhiều lần nhiều lần cho đến khi tôi gọi longjmp sau này?

Mọi thứ hoạt động hoàn hảo, vì vậy chắc chắn có điều gì đó mà tôi không hiểu. Tôi đã hy vọng ai đó có thể làm sáng tỏ điều này.

Cảm ơn!

+0

Có các triển khai setjmp chỉ lưu con trỏ/con trỏ khung (xem 'libunwind'). Những người có setjmp rất nhanh nhưng thời gian longjmp tương đối chậm và được dựa trên các bảng khung mô tả cách khôi phục các thanh ghi khác từ các vị trí được lưu giữ bởi người gọi và như vậy. –

+0

Tôi có thể tìm thấy nguồn bạn đang xem ở đâu? – nullpotent

+0

@AljoshaBre Đây là những điều dễ đọc nhất mà tôi đã tìm thấy cho đến nay: [setjmp] (http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=src/setjmp /x86_64/setjmp.s;h=98f58b8d6551e391f426fc53c81678a03ac89074;hb=HEAD) và [longjmp] (http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=src/ setjmp/x86_64/longjmp.s; h = e175a4b9606bba41eccc8972c22244e533718f0a; hb = HEAD). – haste

Trả lời

4

Chức năng setjmp là một chức năng giống như bất kỳ chức năng nào khác và do đó có thể được giả định là không có bất kỳ thanh ghi lưu giữ người gọi nào. Như vậy, không cần thiết phải lưu/khôi phục những thanh ghi đó.

+0

Không phải trình biên dịch miễn phí sử dụng bất kỳ thanh ghi nào có sẵn vì nó vui lòng bên trong chức năng của tôi, i. e. ngay cả các thanh ghi không được lưu bởi 'setjmp'? – haste

+0

Không hoàn toàn - nó không thể sử dụng đăng ký người gọi lưu trên một cuộc gọi chức năng, bởi vì chúng có thể/sẽ được thay đổi. Ví dụ, xem xét 'eax' (trên x86): callee sẽ viết một giá trị trả về vào thanh ghi đó, vì vậy người gọi không thể lưu trữ bất cứ điều gì quan trọng ở đó qua một cuộc gọi hàm. – duskwuff

+1

@haste tôi cũng đã rơi vào điều này. để mô tả chi tiết hơn một chút: vì chúng được lưu, và setjmp được coi là một hàm bình thường, người gọi setjmp đã lưu các thanh ghi đó nếu cần, vì vậy khi setjmp trả về người gọi lần thứ hai (bởi longjmp) , người gọi sẽ lưu trữ sổ đăng ký người gọi đã lưu trước đó và sẽ có thể khôi phục chúng. –

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