לדלג לתוכן

תוכנית TSR

מתוך ויקיפדיה, האנציקלופדיה החופשית

בסביבת מערכת ההפעלה DOS, תוכנית TSR (ראשי תיבות באנגלית: Terminate and Stay Resident) היא סוג מסוים של תוכנית שנשארת בזיכרון לאחר סיומה, על מנת לחזור לפעולה מאוחר יותר. טכניקה זו אפשרה לעקוף במידה מסוימת את המגבלה המובנית של DOS, שמאפשרת הרצה של תוכנית אחת בכל פעם.

רקע היסטורי

[עריכת קוד מקור | עריכה]

תוכניות TSR הופיעו בשנות ה-1980 המוקדמות ויועדו למחשבים תואמי PC שהריצו את מערכת ההפעלה DOS‏. DOS הייתה מערכת הפעלה שלא תמכה בריבוי משימות, ואפשרה רק לתוכנית אחת לרוץ בכל רגע נתון. עם זאת, ניתן היה לעקוף מגבלה זאת במידה מסוימת ולאפשר ביצוע משימות שונות ברקע, באמצעות תכנות ברמה נמוכה שניצל את מנגנון הפסיקה של מעבד ה-8086. DOS מצידה תמכה באפשרות להשאיר תוכנית שהסתיימה בזיכרון, ובכך לאפשר את הפעלתה מאוחר יותר באמצעות פסיקה.

באמצע שנות ה-1980 הופיע אחד השימושים הבולטים והמזוהים ביותר עם טכניקת ה-TSR: יישומי פופ-אפ, שהופעלו לרוב בלחיצת צירוף מקשים מסוים, ובאמצעות מימוש מנגנון של החלפת הקשר הצליחו לתת למשתמש חוויה של מעין ריבוי-משימות בסיסי ביותר. דוגמה מוקדמת ופופולרית במיוחד ליישום פופ-אפ הייתה Sidekick של בורלנד, שיצאה ב-1984 וכללה מחשבון ועזרי ניהול. באופן דומה, החלו להופיע תוכנות שירות שביצעו משימות שונות ברקע. PRINT.COM, פקודה חיצונית של DOS שסיפקה שירות spooling בסיסי למדפסת, היא דוגמה לכך. בשנים שלאחר מכן גבר השימוש בתוכנות TSR למטרות שונות, כגון תמיכה בהתקנים, שומרי מסך, אנטי-וירוסים ועוד. לשימוש בתוכנות אלה היה תפקיד חשוב בהרחבת אפשרויות השימוש ב-DOS מעבר למגבלותיה המובנות.

סקירה טכנית

[עריכת קוד מקור | עריכה]

סיום התוכנית מבלי לשחרר את הזיכרון

[עריכת קוד מקור | עריכה]

תוכנית רגילה מסיימת את פעולתה על ידי ביצוע קריאת מערכת שמשחררת את הזיכרון ומשאבים אחרים שהוקצו לה ומחזירה את השליטה לתוכנית שהפעילה אותה (בדרך כלל, מעטפת מערכת ההפעלה COMMAND.COM). תוכנית TSR, לעומת זאת, משתמשת בקריאת מערכת ייעודית, שמסיימת את פעולת התוכנית אך מותירה חלק מוגדר מהזיכרון מוקצה עבורה. קריאת המערכת מקבלת כפרמטר את גודל הזיכרון הנדרש, שמוקצה באופן רציף מהכתובת שבה נטענה התוכנית ועד לנקודה הנדרשת. קריאת המערכת המקורית (INT 27h - ‏Terminate but Stay Resident) אפשרה להקצות לתוכנית עד 64K של זיכרון. החל מגרסה 2.0 של MS-DOS, הוצגה קריאת מערכת משופרת (INT 21h Function 31h - Keep Process) שהסירה את המגבלה הזו.

הפעלה מאוחרת באמצעות יירוט פסיקה

[עריכת קוד מקור | עריכה]

מאחר ש-DOS אינה תומכת בריבוי משימות, ברגע שהתוכנית מסתיימת הקוד שלה חדל להיות פעיל. כדי לחזור לפעולה, עליה ליירט פסיקה אחת לפחות; באופן זה ניתן להעביר אליה את השליטה בהמשך באמצעות פסיקת חומרה או תוכנה. יירוט של פסיקה מתבצע על ידי מימוש שגרת טיפול בפסיקה ועדכון המצביע המתאים בטבלת הפסיקות כך שיפנה אליה. התוכנית תשמור את כתובת שגרת הטיפול בפסיקה הקודמת, ובאופן טיפוסי, כדי לאפשר טיפול תקין בפסיקה, השגרה החדשה לא תחליף לחלוטין את הקודמת אלא תוסיף את עצמה לשרשרת: כלומר, תבצע את הנדרש ממנה ותקרא לשגרה הקודמת להמשך טיפול.

יירוט של פסיקת חומרה מאפשר את העברת השליטה לתוכנית באופן אסינכרוני בתגובה לאירוע מסוים: התוכנית יכולה ליירט, למשל, את פסיקת קוצב הזמן (IRQ0/INT 8), שמשוגרת 18.2 פעמים בשנייה, כדי להריץ קוד מסוים ברקע בתדירות זו. התוכנית יכולה גם ליירט את פסיקת בקר המקלדת (IRQ1/INT 9), המשוגרת עם כל לחיצת מקש והרפיה ממנו, כדי לבדוק אם נלחץ צירוף מקשים מסוים ולהגיב בהתאם.

בשונה מיירוט פסיקת חומרה, יירוט של פסיקת תוכנה מאפשר לתוכנית לסנן קריאות לשגרות שירות של DOS ושל BIOS ולשנות את ההתנהגות שלהן כרצונה, או אף לממש ממשק תכנות יישומים (API) משל עצמה. היו תוכנות TSR שהשתמשו בשיטה זו כדי לספק ממשק להתקני חומרה (מעין מנהלי התקנים), לדוגמה: MOUSE.COM, תוכנית שניהלה את העכבר וחשפה API סטנדרטי דרך INT 33h. תוכניות אחרות הרחיבו ממשק קיים, לדוגמה: VESA.COM, שהרחיבה את ממשק ה-BIOS של כרטיס המסך (INT 10h) כדי לאפשר שימוש ברזולוציות של Super VGA בכרטיסי מסך מוקדמים שתמכו בכך אך לא כללו הרחבת קושחה מתאימה.

תוכנית TSR יכולה גם להשתמש ביירוט פסיקת תוכנה כדי לגרום ליישום יעד מסוים להריץ בעקיפין את הקוד שלה בהקשר ידוע (למשל, נקודה מסוימת בקוד היישום שבה מבוצעת קריאת מערכת כלשהי באמצעות הפקודה INT 21h), וכך להשתלב בצורה מבוקרת ומדויקת מאוד בקוד של יישום היעד בזמן הריצה ולשלוט בו באופן מלא. בשיטה זו עשו שימוש תוכנות TSR שביצעו מניפולציה על יישום בזמן הריצה כדי לתקן בו פגמים, או כדי לשנות או להוסיף לו פונקציונליות.

אילוצי זיכרון

[עריכת קוד מקור | עריכה]

טכניקת ה-TSR זכתה אומנם לפופולריות רבה, אך היו לה כמה חסרונות בולטים. הן המשתמשים והן מפתחי התוכנה נאלצו להתמודד עם אילוצים שונים שנבעו, בין השאר, מהאופן שבו DOS, כמערכת הפעלה של real mode,[1] מנהלת את זיכרון המחשב. הבעיה העיקרית הייתה המקום שתפסו תוכניות ה-TSR בזיכרון הראשי (מתחת למחסום ה-640K) על חשבונם של יישומים אחרים. מאחר שהזיכרון הראשי היה מוגבל מאוד, כל תוכנית TSR שנטענה לזיכרון הפחיתה את יתרת הזיכרון הפנוי והגבילה עוד יותר את האפשרות להשתמש ביישומים הצורכים נפח זיכרון גדול.

תוכנית TSR עשויה לאפשר את הסרתה מהזיכרון (uninstall) במקרה הצורך. פעולת ההסרה כרוכה, לכל הפחות, בהשבתת פעילות הרקע של התוכנית על ידי שחזור המצביעים הרלוונטיים בטבלת הפסיקות למצב שקדם לטעינת התוכנית, כך שיפנו לשגרות הטיפול בפסיקה המקוריות, ולאחר מכן שחרור הזיכרון שהוקצה לה. לא כל התוכנות תמכו באפשרות זו, והיו גם תוכנות שאפשרו השבתת תפקוד אך לא הסרה מוחלטת מהזיכרון (תוכנות שירות של צדדים שלישיים אפשרו, בתנאים מסוימים, הסרה של תוכנות סוררות כאלה). כל עוד לא הוסרה, התוכנית ממשיכה לתפוס מקום בזיכרון עד לכיבוי המחשב או הפעלתו מחדש.

מתכנתי TSR השתמשו במגוון טכניקות ואלתורים כדי להתגבר על המגבלה ולצמצם ככל הניתן את צריכת הזיכרון של תוכניות ה-TSR. תוכניות אלה נוטות להיות קומפקטיות מאוד, ולעיתים קרובות ימומשו כקובץ COM. תוכנית TSR טיפוסית תחולק לשניים: חלק אתחול וחלק תושב (resident). חלק האתחול יכיל את כל הקוד שאיננו נחוץ לפעילות התוכנית כאשר היא מתפקדת ברקע, כלומר לאחר החזרת השליטה ל-DOS באמצעות Keep Process. כשחלק זה מסיים את תפקידו, אין בו עוד צורך. כדי לחסוך בזיכרון יכול המתכנת למקם את חלק האתחול בסוף התוכנית, אחרי הקוד והנתונים של החלק התושב, ולסמן את קצה החלק התושב כקצה התוכנית בעת הקריאה ל-Keep Process. בכך ישתחרר הזיכרון שהוקצה עבור חלק האתחול. החלק התושב ממשיך לשכון דרך קבע בזיכרון לאחר סיום התוכנית.

אילוצים נוספים

[עריכת קוד מקור | עריכה]

המתכנתים התמודדו עם קשיים ואילוצים טכניים נוספים מלבד מגבלת הזיכרון. באופן כללי, טכניקת ה-TSR הייתה כרוכה בתכנות מורכב ברמה נמוכה (low-level), שדרש היכרות מעמיקה עם מערכת המחשב ושליטה בשפת סף. DOS היא מערכת הפעלה של real mode[1], ובניגוד למערכות הפעלה מודרניות איננה מספקת שום הגנות או ערבויות ליישומים הפועלים בה - לקוד שרץ ברגע מסוים יש שליטה מוחלטת על מערכת המחשב כולה, והשגיאה הפעוטה ביותר עלולה לגרום בקלות לקריסה של המערכת, ובמקרה הגרוע אף לאובדן נתונים או השחתתם. תכנות בטכניקת ה-TSR מועד במיוחד לתקלות כאלה מעצם טבעו. הטכניקה זכתה לתמיכה רשמית בסיסית בלבד מצד DOS, ויישום יעיל שלה חייב שימוש בקריאות מערכת שלא תועדו (אנ')[2] בגרסאות מוקדמות של מערכת ההפעלה.

כתיבת תוכניות TSR "אקטיביות" - תוכניות שהגיבו לפסיקות חומרה, ובפרט יישומי פופ-אפ - הייתה מאתגרת במיוחד. אחד הקשיים היה הצורך לממש את החלפת ההקשר ברמת היישום, כמעט ללא תמיכה של מערכת ההפעלה. המנגנון הבסיסי של יירוט פסיקות חומרה הוא מטבעו אסינכרוני - כלומר, התוכנית צפויה לקבל לידיה את השליטה בהקשר שרירותי, והדבר אף עלול להתרחש בזמן שמתבצעת פעילות קריטית אחרת, כגון כתיבה לדיסק. היבט זה חייב תשומת לב וזהירות רבה מצדו של המתכנת. בין השאר, היה עליו להתחשב בעובדה ש-DOS ו-BIOS לא תוכננו לריבוי כניסות (reentrancy). לדוגמה, אם התוכנה הפעילה הייתה פונה ל-DOS באמצעות קריאת פסיקה, למשל כדי לקרוא מידע מקובץ, ותוך כדי הטיפול בקריאה זו התקבל קלט מהמקלדת שגרם להפעלת תוכנית ה-TSR וזו מצידה הייתה פונה גם כן ל-DOS, למשל כדי להציג פלט על המסך, אזי שתי הקריאות ל-DOS היו מתנגשות ומחזירות תוצאות שגויות או גורמות למחיקת נתונים וקריסת התוכנה. כדי לפתור את הבעיה נאלצו מפתחי ה-TSR לנטר את כל הקריאות של תוכנות אחרות לפסיקות החשובות להם, ולשמור את הקריאות של עצמן עד לאחר שהפסיקות הקודמות תסתיימנה. אילוצים אלה הוסיפו למורכבות הקוד ולסרבולו. הדבר דרש לעיתים יירוט של פסיקות שונות (כגון INT 13h, ממשק BIOS לקלט/פלט של הדיסק) שלא כחלק מהפונקציונליות של התוכנית אלא רק לצורכי ניטור ובקרה, על ידי עטיפה של שגרת ה-BIOS המקורית ושימוש במשתנה גלובלי או "דגל" שתפקד כמעין מנעול או סמפור אד הוק: השגרה המיירטת לא עשתה הרבה יותר מלהרים את הדגל, לקרוא לשגרה המקורית ולהוריד את הדגל.

מימוש באמצעות הפעלת יישום משנה

[עריכת קוד מקור | עריכה]

טכניקה קרובה מאוד ל-TSR, שלא עשתה שימוש בקריאת Keep Process, הייתה לממש את שגרות הטיפול בפסקה, כבתוכנית TSR רגילה, ולאחר מכן להריץ יישום משנה (child process). בזמן שיישום המשנה פועל, התוכנית מתפקדת ברקע כתוכנית TSR - כלומר, הקוד שלה נשמר בזיכרון ומופעל כשמתבצעת הפסיקה הרלוונטית. עם סגירת יישום המשנה חוזרת השליטה ליישום המפעיל (parent), שאחראי על השבתת הפעילות וביצוע יציאה מסודרת. שיטה זו התאימה במיוחד לתוכניות שתוכננו לביצוע מניפולציה על יישום מסוים בזמן הריצה (ללא שינוי בעותק הפיזי שלו השמור בדיסק), כגון טלאי תוכנה, או טריינר שנועד למשחק מסוים. בנוסף, יש תוכניות שהשתמשו בשיטה זו כדי להריץ עותק נוסף של COMMAND.COM. מימוש זה יצר אפקט דומה מאוד, מנקודת המבט של המשתמש, לתוכנית TSR אמיתית וחסך מהמתכנת את הצורך לטפל בשלב הסרת התוכנית מהזיכרון: שלב זה בוצע באמצעות הפקודה EXIT של COMMAND.COM, שהחזירה את השליטה ליישום המפעיל, שבתורו סיים את התוכנית בדרך הרגילה. החיסרון העיקרי בדרך זו היה הצורך לטעון לזיכרון שני עותקים של COMMAND.COM, דבר שפגע ביכולת לטעון יישומים נוספים.

לקריאה נוספת

[עריכת קוד מקור | עריכה]
  • Tischer, Michael. PC System Programming. Abacus, 1990
  • Duncan, Ray. Advanced MS-DOS Programming: The Microsoft Guide for Assembly Language and C Programmers. 2nd Ed. Microsoft Press, 1990

קישורים חיצוניים

[עריכת קוד מקור | עריכה]

הערות שוליים

[עריכת קוד מקור | עריכה]
  1. ^ 1 2 במעבדים מסדרת x86‏, real mode הוא מצב פעולה פרימיטיבי של 16 סיביות שתואם, פחות או יותר, את ה-8086 המקורי.
  2. ^ על פי המוסכמות בשוק התוכנה, היצרן איננו מחויב לתמוך במאפיינים של התוכנה שאינם מתועדים בספרות הטכנית מטעמו. המשתמש בהם עושה זאת על אחריותו בלבד, בידיעה שייתכן שיוסרו או ישונו ללא התראה בגרסאות עתידיות.