در دامه این مطلب به یک نکته دیگر در زبان اسمبلی خواهیم پرداخت و آن هم مفهوم دستورات فراخوانی و بازگشت زیربرنامه است.
دودستورالعمل که پشته را استفاده می کنند و فراخوانی و برگشت زیربرنامه را انجام می دهند call و ret هستند. برای هدایت کنترل اجرا به زیربرنامه باید آنرا فراخوانی کرد. زیربرنامه ها در هر کجای برنامه که به آن نیاز داریم با دستور call فراخوانی می شوند. دستور call به صورت زیر است:
call ProcedureName
دستورالعمل call باعث یک پرش غیر شرطی به زیربرنامه می شود و آدرس دستورالعمل بعدی را در پشته ذخیره می کند. CPU در برخورد با دستور call به آدرس شروع زیربرنامه رجوع می کند و دستورات آنرا اجرا می نماید. با برخورد به دستور ret به برنامه فراخوان بر می گردد و دستورات بعد از call را اجرا می نماید.
مثال. فراخوانی زیربرنامه Putc.
call Putc
CPU در برخورد با دستور Call عملیات زیر را انجام می دهد:
فراخوانی از نوع داخلی
۱٫ مقدار ثبات IP (که حاوی آدرس دستور بعد از call است ) را در پشته ذخیره می کند.
۲٫ آدرس ذکر شده مقابل دستور call را در ثبات IP قرار می دهد.
فراخوانی از نوع خارجی
۱٫ مقدار ثبات CS را در پشته ذخیره می کند.
۲٫ بخش سگمنت آدرس ذکر شده مقابل دستور call را در ثبات CS قرار می دهد.
۳٫ مقدار ثبات IP را در پشته ذخیره می کند.
۴٫ بخش آفست آدرس ذکر شده در جلوی دستور call را در ثبات IP قرار می دهد.
دستورالعمل ret آدرس ذخیره شده IP را از پشته بر می دارد و به برنامه اصلی بر می گردد. CPU در برخورد با دستور Ret عملیات زیر را انجام می دهد:
بازگشت از زیربرنامه داخلی
۱٫ مقدار ذخیره شده در پشته را در داخل ثبات IP قرار می دهد.
بازگشت از زیربرنامه خارجی
۱٫ مقدار ذخیره شده در پشته را در داخل ثبات IP قرار می دهد.
۲٫ مقدار ذخیره شده در پشته را در داخل ثبات CS قرار می دهد.
نکته. اگر دستور ret در انتهای زیربرنامه حذف شود کنترل اجرای برنامه به زیربرنامه بعدی می رود نه دستورالعمل بعدی در برنامه اصلی.
نکته. معمولا در ابتدای هر زیربرنامه بهتر است مقادیر ثبات هائی که تغییر می کنند را در پشته ذخیره نمائیم و در انتهای زیربرنامه و قبل از دستور ret مقادیر آنها را از پشته بازیابی کنیم. باید توجه کنیم که دستورات pop متناظر با دستورات push باشند و کلیه داده هائی که در زیربرنامه در پشته push شده اند باید pop شوند وگرنه به با دستور ret به آدرس درست پرش نمی کند.
مثال. زیربرنامه برای نمایش ۴۰ کاراکتر space. توجه کنید زیربرنامه Putc درون زیربرنامه PrintSpaces فراخوانی شده است.
PrintSpaces PROC near
push AX
push CX
mov AL, ‘ ‘
mov cx, 40
PSLoop: call putc
loop PSLoop
pop CX
pop AX
ret
PrintSpaces ENDP
در ابتدای زیربرنامه ثبات های AX و CX در پشته قرار می گیرند و در انتها به ترتیب عکس بازیابی می شوند. زیربرنامه فوق به صورت زیر فراخوانی می شود.
call PrintSpace