ในอาร์กิวเมนต์ CDECL จะถูกผลักไปที่สแต็กในลำดับที่กลับกันผู้เรียกจะล้างสแต็กและผลลัพธ์จะถูกส่งกลับผ่านรีจิสตรีโปรเซสเซอร์ (ภายหลังฉันจะเรียกมันว่า "register A") ใน STDCALL มีข้อแตกต่างอย่างหนึ่งคือผู้โทรไม่ได้ล้างสแต็กผู้โทรทำ
คุณกำลังถามว่าอันไหนเร็วกว่า ไม่มีใคร. คุณควรใช้การเรียกแบบดั้งเดิมให้นานที่สุดเท่าที่จะทำได้ เปลี่ยนรูปแบบเฉพาะในกรณีที่ไม่มีทางออกเมื่อใช้ไลบรารีภายนอกที่ต้องใช้แบบแผนบางประการ
นอกจากนี้ยังมีอนุสัญญาอื่น ๆ ที่คอมไพเลอร์อาจเลือกเป็นค่าเริ่มต้นเช่นคอมไพเลอร์ Visual C ++ ใช้ FASTCALL ซึ่งเร็วกว่าในทางทฤษฎีเนื่องจากการใช้งานการลงทะเบียนโปรเซสเซอร์ที่กว้างขวางมากขึ้น
โดยปกติคุณต้องให้ลายเซ็นการเรียกกลับที่เหมาะสมกับฟังก์ชันการโทรกลับที่ส่งผ่านไปยังไลบรารีภายนอกบางอย่างเช่นการเรียกกลับqsort
จากไลบรารี C ต้องเป็น CDECL (หากคอมไพเลอร์โดยค่าเริ่มต้นใช้หลักการอื่นเราต้องทำเครื่องหมายการเรียกกลับเป็น CDECL) หรือการเรียกกลับ WinAPI ต่างๆจะต้องเป็น STDCALL (WinAPI ทั้งหมดคือ STDCALL)
กรณีปกติอื่น ๆ อาจเกิดขึ้นเมื่อคุณจัดเก็บพอยน์เตอร์ไปยังฟังก์ชันภายนอกบางอย่างเช่นเพื่อสร้างตัวชี้ไปยังฟังก์ชัน WinAPI ข้อกำหนดประเภทจะต้องทำเครื่องหมายด้วย STDCALL
ด้านล่างนี้เป็นตัวอย่างที่แสดงให้เห็นว่าคอมไพเลอร์ทำอย่างไร:
i = Function(x, y, z);
int Function(int a, int b, int c) { return a + b + c; }
CDECL:
push on the stack a copy of 'z', then a copy of 'y', then a copy of 'x'
call (jump to function body, after function is finished it will jump back here, the address where to jump back is in registers)
move contents of register A to 'i' variable
pop all from the stack that we have pushed (copy of x, y and z)
copy 'a' (from stack) to register A
copy 'b' (from stack) to register B
add A and B, store result in A
copy 'c' (from stack) to register B
add A and B, store result in A
jump back to caller code (a, b and c still on the stack, the result is in register A)
STDCALL:
push on the stack a copy of 'z', then a copy of 'y', then a copy of 'x'
call
move contents of register A to 'i' variable
pop 'a' from stack to register A
pop 'b' from stack to register B
add A and B, store result in A
pop 'c' from stack to register B
add A and B, store result in A
jump back to caller code (a, b and c are no more on the stack, result in register A)