next up previous contents index
Next: การแปลงภาษา C สำหรับฟังก์ชั่น Recursive Up: การเรียกฟังก์ชั่นในฮาร์ดแวร์ Previous: การแปลงฟังก์ชั่นภาษา C ที่ไม่มีการเรียกฟังก์ชั่นอื่น   Contents   Index

ฟังก์ชั่นที่มีการเรียกฟังก์ชั่นอื่น

ฟังก์ชั่นหรือ Procedure ที่ไม่มีการเรียกฟังก์ชั่นอื่นเรียกว่า leaf procedure ถ้าเป็นฟังก์ชั่นที่เรียกฟังก์ชั่นอื่นเรียกว่า nested procedure ในบางครั้งมีการออกแบบให้ฟังก์ชั่นมีการเรียกตัวเองที่เรียกว่า recursive procedure ที่ทำการโคลนตัวเองออกมา ดังนั้นเราจำเป็นต้องมีความระมัดระวังในการใช้งานรีจีสเตอร์เมื่อมีการเรียกฟังก์ชั่นเหล่านี้

ตัวอย่างเช่น ถ้าโปรแกรมหลักเรียกฟังก์ชั่น A ที่มีอาร์กูเมนต์ที่มีค่าเท่ากับ 3 โดยการเก็บค่า 3 ไว้ในรีจีสเตอร์ $a0 จากนั้นใช้คำสั่ง jal A ไปยังฟังก์ชั่น A ถ้าฟังก์ชั่น A เรียกฟังก์ชั่น B ต่อมาโดยคำสั่ง jal B ที่มีอาร์กูเมนต์ที่มีค่าเท่ากับ 7 ซึ่งก็จะถูกเก็บค่าไว้ใน $a0 เช่นกัน จากกรณีดังกล่าว การทำงานของฟังก์ชั่น A ยังไม่เสร็จสิ้น ซึ่งเกิดความขัดแย้งในการใช้งานรีจีสเตอร์ $a0 ด้วยกัน เช่นเดียวกับการใช้งานรีจีสเตอร์ $ra ในการเก็บค่า return address ของฟังก์ชั่น B ในการนี้จึงจำเป็นต้องมีวิธีการจัดการกับการใช้งานรีจีสเตอร์ดังกล่าว

วิธีการหนึ่งของการแก้ไขปัญหาดังกล่าว คือการเก็บค่ารีจีสเตอร์ที่ต้องรักษาค่าไว้ทั้งหมดลงในสแตก เช่นเดียวกับการเก็บค่ารีจีสเตอร์ $s caller จะทำการ push ค่าอาร์กูเมนต์รีจีสเตอร์ ($a0 - $a3) หรือ รีจีสเตอร์ชั่วคราว ($t0 - $t9)ใดๆ ที่ต้องการใช้งานหลังการเรียกฟังก์ชั่นอื่นลงไปยังสแตก จากนั้น callee จะมีหน้าที่ในการ push ค่า $ra และ ค่า ($s0 - $s7) ใดๆ ที่ถูกใช้งานโดย callee ลงในสแตก โดยที่ stack pointer $sp จะถูกปรับตามการใช้งาน และรีจีสเตอร์ต่างๆ จะมีการคืนค่าตามที่ตั้งไว้ก่อนหน้า



Vara Varavithya 2006-11-06