דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. נתינת ארגונומט לפונקציה?

נתינת ארגונומט לפונקציה?

מתוזמן נעוץ נעול הועבר תכנות
5 פוסטים 2 כותבים 55 צפיות 1 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • שאלתיאלש
    שאלתיאלש
    שאלתיאל
    כתב נערך לאחרונה על ידי
    #1
    mov ecx, -11
    call GetStdHandle
    

    . אאל"ט המקטע קוד הזה נותן ארגונומט לפונקציה (11-)
    לאח"כ זה קורא לפונקציה שקוראת את זה כקבוע.
    ואז מחזירה את הHandle שהוא RAX

    @yossiz אני צודק בהבנה שלי?

    yossizY תגובה 1 תגובה אחרונה
    0
    • שאלתיאלש שאלתיאל
      mov ecx, -11
      call GetStdHandle
      

      . אאל"ט המקטע קוד הזה נותן ארגונומט לפונקציה (11-)
      לאח"כ זה קורא לפונקציה שקוראת את זה כקבוע.
      ואז מחזירה את הHandle שהוא RAX

      @yossiz אני צודק בהבנה שלי?

      yossizY
      yossizY
      yossiz
      כתב נערך לאחרונה על ידי yossiz
      #2

      @שאלתיאל כן, בטח אתה צודק בהבנה שלך
      אבל אפשר להוסיף המון הסבר

      למה 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 שהוא unsigned long שזה א) 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, וגם לזה יש תשובה טובה

      כהנה וכהנה תמיד אפשר וחייבים לחטט ולהיות סקרני

      📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה
      👈 רוצים כתובת מייל בעברית? כנסו למייל.קום 👉

      תגובה 1 תגובה אחרונה
      3
      • yossizY
        yossizY
        yossiz
        כתב נערך לאחרונה על ידי
        #3

        @שאלתיאל קיוויתי בתשובה הנ"ל לתת לך טעימה שתבין למה כדאי לך ללמוד כל הידע המקדים שהספרים/קורסים מנסים ללמד אותך
        למה כדאי להבין שיטת המספור הבינארי, ולמה כדאי להבין שפת C
        מקווה ששיכנעתי אותך קצת

        📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה
        👈 רוצים כתובת מייל בעברית? כנסו למייל.קום 👉

        תגובה 1 תגובה אחרונה
        2
        • yossizY
          yossizY
          yossiz
          כתב נערך לאחרונה על ידי
          #4

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

          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
          

          (היו עוד ביקורות אבל דקויות ממש עדינות שלא כדאי להעלות לפה)

          📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה
          👈 רוצים כתובת מייל בעברית? כנסו למייל.קום 👉

          תגובה 1 תגובה אחרונה
          2
          • שאלתיאלש
            שאלתיאלש
            שאלתיאל
            כתב נערך לאחרונה על ידי
            #5

            @yossiz אתה מסביר ממש יפה חייב לומר, ב. כן. שיכנעת אבל מעדיף קודם כל לדעת אסם לדעתי זה יהיה יותר טוב
            כי אדע בדיוק איך כל פקודה מתורגמת לשפת מכונה

            תגובה 1 תגובה אחרונה
            0

            שלום! נראה שהשיחה הזו מעניינת אותך, אבל עדיין אין לך חשבון.

            נמאס לכם לגלול בין אותם הפוסטים בכל ביקור? כשנרשמים לחשבון, תמיד תחזרו בדיוק למקום שבו הייתם קודם, ותוכלו לבחור לקבל התראות על תגובות חדשות (בין אם במייל, ובין אם בהתראת פוש). תוכלו גם לשמור סימניות ולפרגן ב-upvote לפוסטים כדי להביע הערכה לחברי קהילה אחרים.

            בעזרת התרומה שלך, הפוסט הזה יכול להיות אפילו טוב יותר 💗

            הרשמה התחברות
            תגובה
            • תגובה כנושא
            התחברו כדי לפרסם תגובה
            • מהישן לחדש
            • מהחדש לישן
            • הכי הרבה הצבעות


            בא תתחבר לדף היומי!
            • התחברות

            • אין לך חשבון עדיין? הרשמה

            • התחברו או הירשמו כדי לחפש.
            • פוסט ראשון
              פוסט אחרון
            0
            • דף הבית
            • קטגוריות
            • פוסטים אחרונים
            • משתמשים
            • חיפוש
            • חוקי הפורום