נתינת ארגונומט לפונקציה?
-
mov ecx, -11 call GetStdHandle. אאל"ט המקטע קוד הזה נותן ארגונומט לפונקציה (11-)
לאח"כ זה קורא לפונקציה שקוראת את זה כקבוע.
ואז מחזירה את הHandle שהוא RAX@yossiz אני צודק בהבנה שלי?
@שאלתיאל כן, בטח אתה צודק בהבנה שלך
אבל אפשר להוסיף המון הסברלמה
ecx?
יש פה שתי שאלות,
א) למה רג'יסטרcולאaאוbאו משהו אחר
ב) למה לבחור ב-ecx(גירסת ה-32 סיביות מתוך משפחתc, לעומתrcx) מדובר הרי בקוד של 64 סיביות (עוד שאלה: איך ידעתי מתוך שתי השורות שהבאת שזה 64 סיביות?)התשובה לשאלה הראשונה (וגם לשאלה שבסוגריים בסוף השאלה השנייה) קשורה ל-calling conventions = המוסכמה איך נהוג לקרוא פונקציות בווינדוס 64. וקונבנציה של win64 הוא ששמים את הארגומנט הראשון (מסוג int) ב-
rcx(זה שונה לגמרי מהקונבנציות הן של win32 והן של לינוקס)
אפשר להמשיך ולשאול למה הקונבנציה ככה, אבל קונבנציה כשמו כן הוא, סתם מוסכמה כי חייבים להסכים על שיטה כלשהו, (אולי יש טעם יותר עמוק, אני לא יודע)התשובה לשאלה השניה יותר מסובכת: זה חוזר לאיך מוגדר הקבוע
STD_OUTPUT_HANDLEבקבצי ה-hearders של windows api
ככה זה מוגדר:typedef unsigned long DWORD; #define STD_OUTPUT_HANDLE ((DWORD)-11)(הנה דוגמה מצויינת למה כדאי לך מאוד להכיר שפת C... כי זו השפה שבה מוגדרים ה-API של ווינדוס ולינוקס)
יש פה דקויות שצריך לשים אליהם את הדעת:
א) מה כתוב בשפת C
ה--11כשלעצמו (בשפת C) הואsigned intאבל הערך שהפונקציה מקבלת הוא מסוגDWORDשהוא unsignedlongשזה א) unsigned וב) long דהיינו 32 סיביות, לכן יש casting (= כפייה לטייפ אחר) של הערך ל-DWORD
עכשיו צריך להבין שכאשר אתה כופה -11 לטייפ unsigned ו-unsigned הרי לא יכול לקבל ערך שלילי, אז מה הערך??
התשובה היא:0xFFFFFFF5(למה? ע"ע משלים ל-2)ב) איך זה ממומש באסמבלי
עכשיו כשנבוא לתרגם את זה לאסמבלי ונרצה להעביר את הערך0xFFFFFFF5בתור ארגומנט יש דבר נוסף שצריך לשים עליו לב, וזה שאם נכתובmov rcx, -11אז הערך ש-rcx יקבל יהיה0xFFFFFFFFFFFFFFF5
לכן יש פה שימוש ב-ecx, שעובד אחרי שנדע התנהגות ה"הרחבה" של המעבד, כלומר איך המעבד "מרחיב" מספר בן 32 סיביות לתוך רג'יסטר בן 64 סיביות (התשובה על ידי מילוי המיקומים הריקים ב-0, למרות שבמקרה של מספר signed זה גורם לשינוי הערך של המספר)יש עוד דברים שאפשר לשאול כמו למשל למה ה-API של ווינדוס מגדיר את הקבוע של STD_OUTPUT_HANDLE כמספר שלילי ולא מספר חיובי, וגם לזה יש תשובות טובות, ולמה -11 ולא -1, וגם לזה יש תשובה טובה
כהנה וכהנה תמיד אפשר וחייבים לחטט ולהיות סקרני
-
עכשיו הבאתי את התשובה שכתבתי לקלוד לקבל ביקורת (למען האמת גם בתשובה המקורית נעזרתי קצת בקלוד לבירור כמה דברים, אבל ניסחתי אותה בעצמי) והוא טוען שטעיתי קצת
yossiz כתב:
לכן יש פה שימוש ב-ecx
הוא טוען שבאמת היה אפשר להשתמש גם ב-rcx בעקרון כי ה-ABI (שים לב לניסוח, ABI ולא API, מה ההבדל? נושא לעוד שיעור...) של ווינדוס בפירוש מתעלם מבייטים העליונים כאשר הרוחב של הארגומנט מוצהר כ-DWORD
היתרון של שימוש ב-ecx הוא כי הבינארי של הפקודה קצרה יותר
B9 F5 FF FF FF ; mov ecx, -11 → 5 bytes 48 C7 C1 F5 FF FF FF ; mov rcx, -11 → 7 bytes(היו עוד ביקורות אבל דקויות ממש עדינות שלא כדאי להעלות לפה)
שלום! נראה שהשיחה הזו מעניינת אותך, אבל עדיין אין לך חשבון.
נמאס לכם לגלול בין אותם הפוסטים בכל ביקור? כשנרשמים לחשבון, תמיד תחזרו בדיוק למקום שבו הייתם קודם, ותוכלו לבחור לקבל התראות על תגובות חדשות (בין אם במייל, ובין אם בהתראת פוש). תוכלו גם לשמור סימניות ולפרגן ב-upvote לפוסטים כדי להביע הערכה לחברי קהילה אחרים.
בעזרת התרומה שלך, הפוסט הזה יכול להיות אפילו טוב יותר 💗
הרשמה התחברות