1.8 אקסטרה הרצאה
קפיצות: Near ו־Far¶
מעבד 8086 בנוי לעבוד במודל של סגמנטים. זה אומר שכתובת בזיכרון מורכבת משני חלקים: סגמנט (Segment) ואופסט (Offset).
ולשם כך יש לנו שני סוגי jmp-ים.
קפיצות לקוד בתוך סגמנט הקוד שלנו, וקפיצות לקוד שנמצא בסגמנט מרוחק.
קפיצת Near Jump¶
קפיצת Near Jump מתבצע בתוך אותו סגמנט.
ב־8086, מדובר בקפיצה לכתובת אופסט אחרת בתוך אותו סגמנט קוד (CS לא משתנה).
למשל:
jmp short label ; קפיצה לטווח של -128 עד +127 בתים
jmp near ptr label ; קפיצה לטווח רחב יותר אך בתוך אותו סגמנט
זה נפוץ בקוד פנימי, בתוך אותה פונקציה או אותו מודול.
Far Jump¶
לעומת זאת הFar Jump קורת כאשר אנחנו קופצים או קוראים (גם עם call) לקטע וד שהוא לא בסגמנט הקוד שלנו, (כלומר רחוק)- ואז כדי לקפוץ אליו, ממש נצטרך לשנות את הcs (הcode segement)
זה קורה כשאנחנו כותבים תוכנה מאוד גדולה, (עם קוד יותר מ64k בתים) וזה דורש מאיתנו לכתוב קוד סגמנט אחר.
האסמבלר יודע להמיר את הקוד הזה, ולעשות גם mov לcs לסגמנט הנכון וגם jmp לoffset הנכון.
זה לגבי jmp-ים, אבל מה עם פונקציות שלא בסגמנט הקוד? (כשאנחנו כותבים יותר מידי קוד ואנחנו נדרשים לכתוב פונקציה בסגמנט חדש)
כאשר אנחנו מגדירים פונקציה כזו, אנחנו נגדיר אותה כך:
בכך האסמבלר יודע, שכאשר אנחנו עושים
call לפונקציה "myFunction" היא נמצאת רחוק (לא בסגמנט הקוד שלנו) והאסמבלר ידע לשנות את הcs לסגמנט הנכון, ולעשות jmp לoffset הנכון.הבעיה היא שפונקציה לעומת jmp צריכה לעשות ret לכתובת הנכונה. לשם כך, האסמבלר כמו שהוא עושה push לip, הוא עושה push גם לcs לפני שהוא משנה אותו.
ובכך כשהפונקציה חוזרת, האסמבלר יודע לעשות pop לcs לפני הret.
תוכלו להגדיר פונקצית near ככה:
וכמובן שתוכלו גם להגדיר עם label, (אין הבדל כשמדובר בפונקציות near)
הזזות ימינה ושמאלה: SHL ו־SHR¶
הזזה שמאלה (SHL)¶
מבצעת הכפלה ב־2 על המספר הבינארי, על ידי הזזת כל הביטים שמאלה.
הזזה ימינה (SHR)¶
מבצעת חלוקה ב־2 על ידי הזזת הביטים ימינה. הביט הגבוה הופך ל־0.
שימוש נפוץ: כפל/חילוק מהירים ב־2, 4, 8 וכו.
פקודת החלפה XCHG¶
פקודה שמחליפה בין שני רגיסטרים או בין רגיסטר לזיכרון:
דוגמה:
פקודת LOOP¶
לולאה שמבוססת על רגיסטר CX — בכל פעם ש־loop מתבצעת, היא מקטינה את CX ב־1 ובודקת אם CX ≠ 0.
הפלט יתבצע 5 פעמים.
שימושי מאוד בלולאות פשוטות.
הגדרות בdata segement¶
בdata segement אנחנו יכולים להגדיר משתנים, בין היתר- אנחנו יכולים לבחור גדול למשתנים.