2011-09-12 33 views
18

Chỉ cần bắt đầu học x64 lắp ráp và tôi có một câu hỏi về chức năng, đối số và ngăn xếp. Theo như tôi hiểu, bốn đối số đầu tiên trong một hàm được chuyển tới các thanh ghi rcx, rdx, r8 và r9 (và xmm0-xmm3 cho các float) trong Windows. Vì vậy, một hàm addition tầm thường với bốn thông số sẽ trông như thế này:Có dành không gian ngăn xếp cần thiết cho các chức năng ít hơn bốn đối số không?

add: 
    mov r10, rcx 
    add r10, rdx 
    add r10, r8 
    add r10, r9 
    mov rax, r10 
    ret 

Tuy nhiên, tôi đã đi qua documentation that mentions this:

Tối thiểu, mỗi chức năng phải dự trữ 32 byte (bốn 64 giá trị bit) trên ngăn xếp. Không gian này cho phép đăng ký được chuyển vào hàm để dễ dàng sao chép vào vị trí ngăn xếp nổi tiếng. Chức năng callee là không cần thiết để tràn các thông số đăng ký đầu vào vào ngăn xếp, nhưng việc đặt chỗ ngăn xếp sẽ đảm bảo rằng nó có thể nếu cần thiết.

Vì vậy, tôi có phải đặt trước không gian ngăn xếp ngay cả khi các chức năng tôi đang thực hiện lấy bốn tham số hoặc ít hơn hoặc chỉ là đề xuất?

+1

http://www.agner.org/ optimization/optimizing_assembly.pdf Chương 4 có một ví dụ cho thấy rằng bạn phải * luôn luôn * không gian dự trữ. – user786653

+1

Rất tiếc, đã quá muộn để chỉnh sửa. [oldnewthing] (http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx) mục blog trên quy ước gọi điện thoại amd64. – user786653

+0

Một phần khác của câu đố cho bạn: bạn có một chức năng *** lá ***, có nghĩa là nó không gọi các chức năng khác. – jww

Trả lời

13

Trích dẫn của bạn là từ phần "quy ước cuộc gọi" của tài liệu. Ít nhất, bạn không phải lo lắng về điều này nếu bạn không gọi các hàm khác từ mã assembly của bạn. Nếu bạn làm như vậy, bạn phải tôn trọng, trong số những thứ khác, "khu vực màu đỏ" và cân nhắc liên kết xếp chồng, rằng đề xuất bạn trích dẫn nhằm đảm bảo.

EDIT: this post làm rõ sự khác biệt giữa "vùng màu đỏ" và "không gian bóng".

+0

Tôi đã thấy "vùng màu đỏ" được sử dụng trong tài liệu Hệ thống V, nhưng tài liệu Windows sử dụng "không gian bóng". Những thứ này có giống nhau không? Nếu không ai biết, tôi sẽ hỏi trong một câu hỏi khác. –

+0

Trả lời một phần bản thân mình: không, "vùng màu đỏ" và "không gian bóng tối" không giống nhau. "Không gian bóng" là tên của 32 byte được đặt trên ngăn xếp. Nó được dành riêng bởi người gọi, vì vậy nó không phải là tùy chọn nếu bạn muốn bạn có thể gọi được với ABI thông thường, nhưng bạn không cần phải lo lắng về nó. –

+0

Vì vậy, tất cả tôi sẽ phải làm gì để làm cho rằng mẫu mã trên "đúng" là thêm 'phụ rsp, 32' để bắt đầu và 'thêm rsp, 32' để kết thúc, chính xác? – Don

0

Tôi chỉ gặp phải điều này mà không biết và có vẻ như vậy. Hai hướng dẫn đầu tiên trong GetAsyncKeyState chẳng hạn ghi đè lên ngăn xếp phía trên giá trị trả về trong vùng byte 0x20 mà bạn phải đặt trước để sử dụng cho tham số:

user32.GetAsyncKeyState - mov [rsp+08],rbx 
user32.GetAsyncKeyState+5- mov [rsp+10],rsi 
user32.GetAsyncKeyState+A- push rdi 
user32.GetAsyncKeyState+B- sub rsp,20 
Các vấn đề liên quan