Tôi sẽ thêm một câu trả lời khác, để giải quyết một số cuộc thảo luận tiếp tuyến đã diễn ra.
C ABI (giao diện nhị phân ứng dụng) ban đầu được gọi để truyền các đối số trên ngăn xếp theo thứ tự ngược lại (nghĩa là - được đẩy từ phải sang trái), trong đó người gọi cũng giải phóng bộ lưu trữ ngăn xếp. ABI hiện đại thực sự sử dụng các thanh ghi để truyền các đối số, nhưng nhiều cân nhắc xáo trộn quay trở lại đối số ngăn xếp ban đầu đó.
Ngược lại, Pascal ABI ban đầu đã đẩy các đối số từ trái sang phải và callee phải bật các đối số. C ABI ban đầu vượt trội so với Pascal ABI ban đầu ở hai điểm quan trọng. Thứ tự đẩy đối số có nghĩa là phần bù ngăn xếp của đối số đầu tiên luôn được biết đến, cho phép các hàm có số lượng đối số không xác định, trong đó các đối số đầu kiểm soát có bao nhiêu đối số khác (alaprintf
).
Cách thứ hai mà C ABI vượt trội là hành vi trong trường hợp người gọi và callee không đồng ý về việc có bao nhiêu đối số. Trong trường hợp C, miễn là bạn không thực sự truy cập các đối số qua câu hỏi cuối cùng, không có gì xấu xảy ra. Trong Pascal, số lượng đối số sai được bật ra từ ngăn xếp và toàn bộ ngăn xếp bị hỏng.
Windows 3.1 ABI ban đầu được dựa trên Pascal. Như vậy, nó đã sử dụng Pascal ABI (các đối số theo thứ tự từ trái sang phải, callee bật lên). Vì bất kỳ sự không phù hợp nào trong số đối số có thể dẫn đến tham nhũng ngăn xếp, một sơ đồ xáo trộn đã được hình thành. Mỗi tên hàm được xáo trộn với một số chỉ kích thước, tính bằng byte, của các đối số của nó. Vì vậy, trên máy 16 bit, hàm sau (cú pháp C):
int function(int a)
Được đọc sai function@2
, vì int
rộng hai byte. Điều này đã được thực hiện để nếu khai báo và định nghĩa không khớp, trình liên kết sẽ không tìm thấy hàm thay vì làm hỏng ngăn xếp trong thời gian chạy. Ngược lại, nếu chương trình liên kết, thì bạn có thể chắc chắn số byte chính xác được bật ra từ ngăn xếp ở cuối cuộc gọi.
Windows 32 bit trở đi sử dụng stdcall
ABI thay thế. Nó tương tự như Pascal ABI, ngoại trừ thứ tự đẩy giống như trong C, từ phải sang trái. Giống như Pascal ABI, tên xáo trộn kích thước byte đối số vào tên hàm để tránh tham nhũng ngăn xếp.
Không giống như các khiếu nại được đưa ra ở nơi khác, C ABI không xáo trộn các tên hàm, ngay cả trên Visual Studio. Ngược lại, các hàm xáo trộn được trang trí với stdcall
đặc tả ABI không phải là duy nhất đối với VS. GCC cũng hỗ trợ ABI này, ngay cả khi biên dịch cho Linux. Điều này được Wine sử dụng rộng rãi , sử dụng trình tải riêng của nó để cho phép chạy thời gian liên kết các tệp nhị phân được biên dịch Linux với các tệp DLL được biên dịch của Windows.