ฉันจะเพิ่มคำตอบอีกหนึ่งคำตอบเพื่อจัดการกับการสนทนาเชิงสัมผัสที่เกิดขึ้น
C ABI (แอปพลิเคชั่นไบนารีอินเทอร์เฟซ) เดิมเรียกว่าสำหรับการส่งผ่านอาร์กิวเมนต์บนสแต็กในลำดับย้อนกลับ (เช่น - ผลักจากขวาไปซ้าย) โดยที่ผู้เรียกยังปลดปล่อยที่เก็บสแต็ก Modern ABI ใช้การลงทะเบียนในการส่งผ่านอาร์กิวเมนต์ แต่ข้อควรพิจารณาหลายประการกลับไปที่อาร์กิวเมนต์สแต็กเดิมที่ส่งผ่าน
ในทางตรงกันข้าม Pascal ABI ดั้งเดิมผลักอาร์กิวเมนต์จากซ้ายไปขวาและ callee จะต้องแสดงอาร์กิวเมนต์ C ABI ดั้งเดิมเหนือกว่า Pascal ABI ดั้งเดิมในสองจุดสำคัญ ลำดับการพุชอาร์กิวเมนต์หมายความว่าทราบค่าออฟเซ็ตสแต็กของอาร์กิวเมนต์แรกเสมอโดยอนุญาตให้ฟังก์ชันที่มีอาร์กิวเมนต์ไม่ทราบจำนวนโดยที่อาร์กิวเมนต์แรกจะควบคุมจำนวนอาร์กิวเมนต์อื่น ๆ (ala printf
)
วิธีที่สองที่ C ABI เหนือกว่าคือพฤติกรรมในกรณีที่ผู้โทรและผู้โทรไม่เห็นด้วยกับจำนวนข้อโต้แย้งที่มี ในกรณี C ตราบใดที่คุณไม่ได้เข้าถึงอาร์กิวเมนต์ที่ผ่านมาจริงๆจะไม่มีอะไรเลวร้ายเกิดขึ้น ในภาษาปาสคาลจำนวนอาร์กิวเมนต์ผิดจากสแต็กและสแต็กทั้งหมดเสียหาย
Windows 3.1 ABI ดั้งเดิมนั้นใช้ภาษาปาสคาล ด้วยเหตุนี้จึงใช้ Pascal ABI (อาร์กิวเมนต์เรียงลำดับจากซ้ายไปขวา callee pops) เนื่องจากหมายเลขอาร์กิวเมนต์ที่ไม่ตรงกันอาจนำไปสู่ความเสียหายของสแต็กจึงเกิดโครงการโกงกิน ชื่อฟังก์ชั่นแต่ละชื่อถูกทำให้ยุ่งเหยิงด้วยตัวเลขที่ระบุขนาดของอาร์กิวเมนต์เป็นไบต์ ดังนั้นบนเครื่อง 16 บิตฟังก์ชันต่อไปนี้ (ไวยากรณ์ C):
int function(int a)
พังทลายไปfunction@2
แล้วเพราะint
กว้างสองไบต์ สิ่งนี้ทำเพื่อที่ว่าหากการประกาศและคำจำกัดความไม่ตรงกันตัวเชื่อมโยงจะไม่พบฟังก์ชันแทนที่จะทำให้สแตกเสียหายในขณะรัน ในทางกลับกันหากโปรแกรมเชื่อมโยงคุณสามารถมั่นใจได้ว่าจำนวนไบต์ที่ถูกต้องถูกดึงออกจากสแต็กเมื่อสิ้นสุดการโทร
Windows 32 บิตเป็นต้นไปให้ใช้stdcall
ABI แทน คล้ายกับ Pascal ABI ยกเว้นคำสั่งกดจะเหมือนใน C จากขวาไปซ้าย เช่นเดียวกับ Pascal ABI ชื่อที่ยุ่งเหยิงจะเปลี่ยนขนาดของอาร์กิวเมนต์ไบต์ในชื่อฟังก์ชันเพื่อหลีกเลี่ยงความเสียหายของสแต็ก
ซึ่งแตกต่างจากการอ้างสิทธิ์ที่อื่นที่นี่ C ABI จะไม่ยุ่งเกี่ยวกับชื่อฟังก์ชันแม้แต่ใน Visual Studio ในทางกลับกันฟังก์ชั่นการดัดแปลงที่ตกแต่งด้วยstdcall
ข้อกำหนด ABI นั้นไม่ซ้ำกับ VS GCC ยังรองรับ ABI นี้แม้ว่าจะคอมไพล์สำหรับ Linux ก็ตาม สิ่งนี้ถูกใช้อย่างกว้างขวางโดยWineซึ่งใช้ตัวโหลดของตัวเองเพื่อให้สามารถเชื่อมโยงเวลาทำงานของไบนารีที่คอมไพล์ของ Linux กับ DLL ที่คอมไพล์ของ Windows