Return Instruction — funksiya bajarilishini tugatib, boshqaruvni saqlangan qaytish manziliga uzatadigan protsessor buyrug‘i yoki buyruqlar ketma-ketligi. U Call Instruction yaratgan davom etish nuqtasidan dasturni tiklaydi. Returnning to‘g‘ri ishlashi apparat semantikasi bilan birga calling convention va stek freymining buzilmaganligiga bog‘liq.
Manzilni olish
Stekka asoslangan ISAda return yuqoridagi manzilni program counterga yuklab, stek ko‘rsatkichini siljitishi mumkin. Link registrli arxitekturada u shu registrga bilvosita jumpning maxsus ko‘rinishi bo‘ladi. Agar funksiya boshqa funksiya chaqirgan bo‘lsa, prologda saqlangan eski link registr epilogda avval tiklanadi.
Ba’zi buyruq shakllari qaytish bilan birga stekdan argument maydonini ham olib tashlaydi. Buni kim bajarishi ABI tomonidan belgilanadi. Chaqiruvchi va chaqiriluvchi turlicha qoida ishlatsa, stek ko‘rsatkichi siljib, keyingi return yoki mahalliy ma’lumot buziladi.
Epilog
Returndan oldin callee-saved registrlar, freym ko‘rsatkichi va stek ko‘rsatkichi tiklanadi. Istisno orqali chiqish odatiy epilogdan o‘tmasligi mumkin; tilning unwind mexanizmi freymlar bo‘ylab yurib resurs tozalash kodini chaqiradi. Debugger ham stack unwinding ma’lumotidan chaqiruvlar zanjirini tiklashda foydalanadi.
Tail call holatida joriy funksiya natijani bevosita boshqa funksiyadan qaytaradi. Kompilyator yangi qaytish manzilini saqlamasdan joriy freymni tugatib, callee’ga jump qilishi mumkin. Natijada stek chuqurlashmaydi, ammo oddiy profil yoki backtrace’da oraliq freym ko‘rinmasligi ehtimoli bor.
Bashorat
Bilvosita return nishoni odatda xotiradan yoki registrdan kech ma’lum bo‘ladi. Protsessor Return Address Stack yordamida calllarda ko‘rilgan manzillarni LIFO tartibida bashorat qiladi. Oddiy ichma-ich chaqiruvlarda bu juda aniq. Istisno, coroutine, noodatiy stek boshqaruvi yoki chuqurlik chegarasi predictor holatini mos kelmas qilishi mumkin.
Noto‘g‘ri bashorat quvurdagi spekulyativ buyruqlarni bekor qilish jarimasini keltiradi. Me’moriy return manzili baribir stek yoki link registrdagi haqiqiy qiymatdan olinadi.
Himoya
Qaytish manzili boshqaruv oqimining yuqori qiymatli elementi. Stek buferi chegaradan oshib yozsa, hujumchi uni almashtirishga urinadi. Stack canary ma’lumot buzilishini return oldidan aniqlaydi; shadow stack qaytish manzilining alohida himoyalangan nusxasini saqlaydi. Control-flow enforcement apparati odatiy stek va soyali nusxa mos kelmasa bajarishni to‘xtatishi mumkin.
Return foydalanuvchi funksiyasidan qaytish bilan cheklanadi. Interrupt yoki istisnodan qaytish maxsus buyruq bo‘lib, program counter bilan birga holat bayroqlari va ba’zan imtiyoz darajasini tiklaydi; shu sabab unga kuchliroq ruxsat tekshiruvi qo‘llanadi.
Korutina yoki continuation odatiy LIFO call stack tartibini buzishi mumkin. U bajarilish kontekstini alohida obyektga saqlab, keyin boshqa stekda davom etadi; oddiy return address predictor buni call/return jufti sifatida tushunmasligi mumkin. Til runtime’i stekni almashtirganda garbage collector va debugger uchun ildizlar hamda unwind ma’lumotini yangilaydi. Bu holat return buyrug‘ining kichik semantikasi bilan yuqori darajadagi “funksiyadan qaytish” tushunchasi har doim aynan bir xil emasligini ko‘rsatadi.
Epilogdagi stek ko‘rsatkichi tekshiruvi buzilgan freymni erta aniqlashi mumkin. Shunga qaramay, xotira xavfsiz til va apparat himoyasi bir-birini to‘ldiradi; bittasi barcha bilvosita nazorat oqimi xatolarini qoplamaydi.
Istisno ishlovchisidan odatiy return bilan chiqish mumkin emas, chunki saqlangan kontekstda oddiy funksiya registrlaridan ko‘proq holat mavjud. Maxsus qaytish yo‘li uzilish niqobi va imtiyoz holatini tekshiradi hamda tiklaydi.
Bog‘liq tushunchalar
call instruction, return address, stack frame, stack unwinding, return prediction, shadow stack