קריאה מהאקטרה סגמנט

עמוד

הדיון הזה מכיל 16 תגובות, ויש לו 3 משתתפים, והוא עודכן לאחרונה ע״י  adi לפני 1 שנה, 7 חודשים.

מוצגות 15 תגובות – 1 עד 15 (מתוך 17 סה״כ)
  • מאת
    תגובות
  • #83299

    ilanbilan
    משתתף

    הבנתי בתחרות האחרונה שרוב השורדים קוראים את השורה הבאה של הקוד שלהם מהאקטרה סגמנט,
    הם מעתיקים את הקוד לאקטרה סגמנט עם MOVSW אבל איך הם בדיוק קוראים משם? או מעתיקים משם את הפקודה הבאה??

    #83300

    Idan Dor
    משתתף

    כתיבה לאקסטרא סגמנט וקריאה מהאקטרה סגמנט זה בעצם כמעט אותו הדבר. movsw תמיד מעתיק שתי בתים מ ds:si ל es:di כלומר, אם נחליף את הסגמנטים es ו ds נאפס את si ונשנה את di למקמונו הנוכחי +1 הפקודה movsw תעתיק את שתי הבתים הראשונים ב es לאחרי ה movsw.
    כמובן שדבר כזה מעתיק רק שני בתים אז צריך לדאוג לכך שלפחות אחד משני הבתים האלו הוא גם movsw ובסופו של דבר צריך לאפס שוב את si כי אחרת הוא יצא מהאזור שמותרת לך גישה אליו וכו.
    אבל באופן הבסיסי זה פשוט איך שאמרתי בהתחלה.

    #83301

    ilanbilan
    משתתף

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

    #83302

    Idan Dor
    משתתף

    במובן הבסיסי כן, אבל לא בדיוק. תזכור שלא כל פקודה היא באורך של בית אחד בלבד, כלומר, אם אתה רוצה להריץ פקודה ארוכה מבית אחד אתה צריך כמה movsw לפני כן.
    לדוגמא, השורד bash מהשנה מריץ במשך הרבה זמן מזמן הריצה שלו את הפקודות pushf ו movsw. בגלל שאורך הפקודה pushf היא בית אחד אז אפשר שכל פקודה שנייה תיהיה movsw.
    לעומת זאת, אם אתה רוצה להריץ את הפקודה mov ax, 0x1234 אז אתה צריך שלושה פקודות movsw לפני כן (ופקודת movsw אחרי) כי אורך הפקודה הוא 3 בתים.
    דוגמא נוספת:
    אם תסתכל בקוד של שורד שפרסמתי בדף "בדיקה האם עליתי על עצמי" שהוא הדף הבא, אז תוכל לראות שרשמתי את הפקודה movsw כמה פעמים ברצף לפני קוד הקפיצה כי קוד הקפיצה חייב להיות לא מפורק (כי הוא משנה את di) ולכן צריך להעתיק את כולו לפני הרצתו.

    #83303

    adi
    משתתף

    בנוסף, מומלץ לציין שאחרי כמות movsw מסויימת יהיה לך מומלץ להשתמש במקום בrep movsw (בקטעי אתחול למיניהם)
    לדוגמה בקוד שמצורף למטה (לא בדקתי אבל אני מעריך שכן) להשתמש בmovsw בין הפקודות יהיה איטי יותר וידרוש ממך יותר בתים- דבר שלא טוב מבחינתך ולכן יהיה עדיף להשתמש בrep movsw
    mov cl,(@junkEnd-@junkStart+1)/2
    rep movsw
    @junkStart:
    nop
    nop
    db 0xc0
    nop
    nop
    nop
    nop
    nop
    @junkEnd:

    #83304

    ilanbilan
    משתתף

    אוקי.. אז איך אני יודע כמה אני אמור לשים בdi ובsi בהתחלה אחרי שהעתקתי את הקוד לאקסטרה סגמנט? אני נמצא בקטע קוד שהוא לא בהתחלה ולא בסוף..

    #83305

    adi
    משתתף

    di צריך להיות המיקום שלך +1, יש לך את המיקום ההתחלתי בax ואתה יכול לעבוד עם לייבלים כי זה חוסך עבודה
    נגיד
    mov di,ax
    add di,@here
    movsw
    @here:

    ———————
    si אתה באופן אישי צריך לקבוע איפה אתה רוצה להתחיל לקרוא מES, אין לי איך להגיד לך..
    בעיקרון si צריך להיות איפה שאתה רוצה שיתחילו לקרוא מES- כי ככה movsw עובד

    #83306

    ilanbilan
    משתתף

    ניסיתי ליצור קוד שקורא מהאקסטרה סגמנט אז ניסיתי להחליף את הסגמנטים עם push (הוא לא נותן לי פשוט עם MOV ..)
    והקוד קורס במשחק בדיוק בנקודה הזאת..

    PUSH DS
    push es
    pop ds
    POP ES

    זה אמור להחליף את הסגמנטים לא?

    #83307

    adi
    משתתף

    הוא קורס בסוף הפקודות האלה לאחר שימוש בmovsw?
    אם כן תבדוק שהsi שלך לא גדול יותר מES
    אם קורס לאחר השימוש בpush הראשון, אז כנראה שהsp שלך היה גדול יותר מSS

    #83308

    ilanbilan
    משתתף

    לא זה ולא זה, אני אומר לך מאה אחוז הוא קורס כשאני מגיע לPOP עברתי על זה מלא פעמים שמתי JMP START במקומות שונים כדי לראות איפה זה קורס וזה קרס בPOP…
    המנוע כותב שעשיתי שגיאת זיכרון,
    אולי אסור לעשות פופ לDS? אם כן איך אני אמור להחליף בין הסגמנטים??

    #83309

    Idan Dor
    משתתף

    כפי שתוכל לראות אם פשוט תכתוב את השורד הבא:
    push es
    push ds
    pop es
    pop ds
    jmp $

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

    #83310

    ilanbilan
    משתתף
    IDEAL
    model tiny
    CODESEG
    org 100h
    start:
    mov cx,(exit-start)
    shr cx,1
    inc cx
    mov si,ax
    mov di,500;אמור לכתוב את הקוד באקסטרה סגמנט
    rep movsw
    PUSH DS
    push es
    pop ds
    POP ES;אמור להחליף בין הסגמנטים
    mov di,ax;מיקום להפציץ
    add di,(exit-start);להתחיל להפציץ אחרי הקוד שלנו
    mov cx,64
    mov dx,0cccch
    attack:
    mov [di],dx
    add di,1024
    loop attack
    mov cx,(exit-start);אחרי 64 הפצצות תכתוב את הקוד מחדש במיקום אחר
    shr cx,1
    inc cx
    mov si,0
    add ax,1863
    mov di,ax
    rep movsw;מתוך האקסטרה סגמנט
    PUSH DS
    push es
    pop ds
    POP ES; להחליף בחזרה כיוון שזה רקורסיבי
    JMP ax
    exit:
    end start 
    #83311

    Idan Dor
    משתתף

    אוקיי, קודם כל כמה הערות כלליות:
    1) מומלץ להשתמש פשוט בשורה
    mov cx,(exit-start + 1)/2
    כדי להפוך את cx לגודל הנכון.
    2) אני ממליץ לך להשתמש ב assembler בשם fasm, שבו אתה לא צריך לרשום את הדברים בתחילת הקוד שלך ואתה יכול פשוט לרשום את הקוד.
    3) כדי לאפס אוגר מסוים, אפשר לחסוך בית בכך שעושים לו xor עם עצמו במקום לעשות אליו mov 0.

    עכשיו לגבי למה הקוד שלך מת, מיקומים בזיכרון (כלומר, אוגרים בסוגריים מרובעות) מתוכנתים ברמה הבינארית כך:
    000 : DS:[BX+SI]
    •001 : DS:[BX+DI]
    •010 : SS:[BP+SI]
    •011 : SS:[BP+DI]
    •100 : DS:[SI]
    •101 : DS:[DI]
    •110 : SS:[BP]
    •111 : DS:[BX]
    כלומר, כאשר אתה מנסה לגשת למיקום [di] כפי שאתה עושה, בגלל החלפת הסגמנטים שלך אתה מנסה לגשת למיקום di באזור המשותף שהוא כמובן מחוץ לתחום ולכן אתה מת.

    עכשיו, כדי לגרום לקוד שלך לעבוד אתה צריך לעשות את השינויים הבאים:
    העברת החלפת הסגמנטים לאחרי לולאת ההפצצה.
    הורדת השורה mov di, 500, אין לי שמץ של מושג למה אתה מריץ אותה, בגללה אתה מעתיק קוד לאמצע es במקום לתחילתו (ואחר כך אתה מנסה לקרוא מתחילת האזור המשותף עם si מאופס). במקום השורה הזאת אתה צריך לשים את השורה xor di, di שתאפס את di לאחר הקפיצה הראשונה שלך.
    לאחר שתעשה את שתי השונויים האלו הקוד שלך יעבוד.

    #83312

    adi
    משתתף

    המלצה קטנה- במקום להשתמש בmov [di],dx אתה יכול להשתמש בpush dx (כאשר ss על הזירה)
    ככה תחסוך לך את החלפת הסגמנטים בכל פעם וגם push פקודה משמעותית יותר קטנה מבחינת בתים ולכן יש פחות סיכוי שתיפגע 🙂

    #83313

    ilanbilan
    משתתף

    1. תודה רבה עידן אני עוד לא ניסיתי את העצות שלך כיוון שאני למדתי למבחן בפיסיקה שיש לי מחר אבל אני מתכוון להחל את העצות עוד כמה דקות
    2.עדי אמנם push פעולה טובה יותר אבל היא פעולה רציפה ואני רוצה להפציץ במרווחים גדולים..

מוצגות 15 תגובות – 1 עד 15 (מתוך 17 סה״כ)

יש להתחבר למערכת על מנת להגיב.