Tôi đang viết một chức năng trong hội đồng x86 mà nên được gọi từ mã c, và tôi tự hỏi đăng ký nào tôi phải khôi phục trước khi tôi trở lại người gọi. Hiện tại tôi chỉ khôi phục lại đặc biệt và ebp, trong khi giá trị trả về nằm trong eax. Có bất kỳ sổ đăng ký nào khác mà tôi nên quan tâm hay tôi có thể để lại bất kỳ điều gì vui lòng cho tôi trong đó không?Thanh ghi nào được khôi phục sau khi gọi hàm x86 trong c?
Trả lời
Sử dụng Microsoft's 32 bit ABI, EAX
, EDX
và ECX
là các thanh ghi đầu, mọi thứ khác phải được giữ nguyên.
Đối với x64 trong môi trường Windows, Microsoft says bạn chỉ cần khôi phục RBX
, RBP
, RDI
, RSI
, R12
, R13
, R14
, và R15
.
Đối với x64 dưới bất cứ điều gì sau System V & AMD64 (see figure 3.4), nó RBP
, RBX
, RSP
, R12
, R13
, R14
, và R15
(họ có vẻ lạ vì hạt nhân sử dụng một tập các thanh ghi và mã Userland sử dụng bộ khác, điều này được quy định trong phụ lục A của tài liệu ABI).
32-bit: EBX, ESI, EDI, EBP
64-bit Windows: RBX, RSI, RDI, RBP, R12-R15, XMM6-XMM15
64-bit Linux,BSD,Mac: RBX, RBP, R12-R15
Để biết chi tiết xem "Software optimization resources" của Agner Fog. Quy ước cuộc gọi được mô tả trong this pdf.
Đừng quên RSP =) –
@StephenCanon, và EIP/RIP :) –
bạn biết đấy, tôi cũng sẽ chỉ ra điều đó, nhưng lệnh 'ret' sẽ xử lý con trỏ chỉ dẫn cho bạn. –
nếu bạn không chắc chắn về tình huống của người đăng ký, những hướng dẫn dưới đây có thể tiết kiệm trong ngày dễ dàng.
PUSHA/PUSHAD -- Push all General Registers
POPA/POPAD -- Pop all General Registers
Những hướng dẫn đẩy và bật các mục đích chung và thanh ghi SI/ESI, DI/EDI theo thứ tự nhất định.
Thứ tự cho lệnh PUSHA/PUSHAD như sau.
Opcode Instruction Clocks Description
60 PUSHA 18 Push AX, CX, DX, BX, original SP, BP, SI, and DI
60 PUSHAD 18 Push EAX, ECX, EDX, EBX, original ESP, EBP ESI, and EDI
Và thứ tự lệnh POPA/POPAD như sau. (theo thứ tự ngược lại)
Opcode Instruction Clocks Description
61 POPA 24 Pop DI, SI, BP, SP, BX, DX, CX, and AX
61 POPAD 24 Pop EDI, ESI, EBP, ESP(***),EBX, EDX, ECX, and EAX
*** Giá trị ESP được loại bỏ thay vì được nạp vào ESP.
Hướng dẫn 'POPA' và' POPAD' không thực sự bật thanh ghi (E) SP! Ngoài ra, vui lòng sửa lỗi trên 'POPAD': bạn đã quên đăng ký EBX. Hơn nữa, bạn nói sai rằng các hướng dẫn này chạm vào * đăng ký phân khúc *! –
Không có quy tắc chung - bạn sẽ phải tham khảo tài liệu của trình biên dịch C để xem những gì nó mong đợi. –
Tôi khá chắc chắn quyền của Jerry, và nó phụ thuộc vào quy ước gọi điện thoại; nếu bộ nhớ phục vụ, có khác nhau "tiêu chuẩn" quy ước trên Windows, Posix vv Trình biên dịch bạn đang sử dụng? –
gcc. Tôi tìm thấy điều này tìm kiếm http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions (xem chuỗi thoát), nhưng nó không nói bất cứ điều gì về sổ đăng ký, chỉ cần chúng được khôi phục về trạng thái mà người gọi mong đợi. – bobbaluba