1.3 בקרת זרימה ולולאות הרצאה
דגלים (Flags), השוואות (CMP) ופקודות קפיצה (JMP, Jcc)¶
רגיסטר FLAGS – מהו?¶
לצד הרגיסטרים הרגילים, למעבד יש רגיסטר מיוחד בשם FLAGS שמכיל דגלים – ביטים שמתעדכנים אוטומטית לאחר כל פעולה אריתמטית או לוגית.
הדגלים משמשים את המעבד להחלטות כמו האם לקפוץ, להמשיך או לעצור.
למה זה חשוב?¶
נוכל לבדוק את מצב הדגלים בעזרת פקודות קפיצה מותנית, וכך לבצע לוגיקה בתוכנית – לולאות, תנאים, בחירות.
הדגלים העיקריים¶
| שם | קיצור | מתעדכן מתי? | משמעות |
|---|---|---|---|
| Carry Flag | CF | חיבור/חיסור/כפל/חילוק | נשיאת ביט – overflow ב־unsigned, נדלק כאשר תוצאת החיבור, חיסור, כפל או חילוק ביצעה overflow |
| Zero Flag | ZF | אם תוצאה = 0 | שווה לאפס? |
| Sign Flag | SF | אם הביט העליון = 1 | תוצאה שלילית (Signed) |
| Overflow Flag | OF | חרג מהטווח של signed | חריגת Overflow ב־signed |
| Parity Flag | PF | אם יש מספר זוגי של ביטים = 1 | בדיקת זוגיות ביטים |
| Auxiliary Carry | AF | ב־BCD | נדיר לשימוש |
מצב הoverflow קורה, כאשר למשל אנחנו מכפילים שני מספרים בעלי 8 ביט למספר 16 ביט. ותוצאת החיבור היא גדולה יותר ממספרי 16 ביט.
כאשר המצב קורה במספרים signed- ידלק דגל הoverflow.
כאשר המצב קורה במספרים unsigned- ידלק דגל הcarry
כאשר נבצע פעולת חיסור בין שני מספרים ונקבל 0, דגל הzero ידלק.
כאשר נבצע פעולת חיסור בין שני משתנים ונקבל מספר שלילי, דגל הsign ידלק.
פקודת השוואה CMP¶
מה היא עושה?¶
פקודת cmp משווה בין שני ערכים כאילו עשתה חיסור – אך לא משנה את הערכים עצמם.
המטרה: לעדכן את הדגלים בהתאם להשוואה.
כלומר, אם ax פחות bx יצא אפס, משמע ax וbx בעל אותו ערך (שווים) ודגל הzero ידלק.
מה נבדק בפועל?¶
- הדגל ידלוק ZF = 1 אם התוצאה היא 0 (כלומר: שווים)
- הדלק ידלוק SF = 1 אם התוצאה שלילית (כלומר: ax < bx עבור signed)
פקודות קפיצה¶
פקודות קפיצה מתחלקות ל־2 סוגים עיקריים:
-
קפיצה ללא תנאי – תמיד תקפוץ
-
קפיצה מותנית – תקפוץ רק אם דגלים מסוימים מופעלים
קפיצה ללא תנאי – JMP¶
קופצת באופן מיידי לתווית (Label) מסוימת בקוד – בלי קשר לדגלים.
למשל בקטע קוד הבא יש לנו 2 label-ים.
באמצע הlabel של start, נתו הוראת jmp לend. כך שההוראה "mov, ax, 2 בחיים לא תקרה."
קפיצות מותנות – Jcc (Jump on Condition Code)¶
מתבצעות רק אם תנאי מסוים מתקיים לפי מצב הדגלים.
שם הפקודה מתחיל ב־J, ואחריו 2 אותיות שמייצגות תנאי.
השוואת שוויון¶
| פקודה | קיצור | תנאי | דגל |
|---|---|---|---|
JE label |
Jump if Equal | אם שווה | ZF = 1 |
JNE label |
Jump if Not Equal | אם שונה | ZF = 0 |
JZ label |
Jump if Zero | תוצאה = 0 | ZF = 1 |
JNZ label |
Jump if Not Zero | תוצאה ≠ 0 | ZF = 0 |
| ### קפיצות על סמך גדול/קטן – Unsigned |
| פקודה | תנאי | הסבר |
|---|---|---|
JA |
Jump if Above | CF=0 ו־ZF=0 (A > B) |
JAE |
Jump if Above or Equal | CF=0 (A ≥ B) |
JB |
Jump if Below | CF=1 (A < B) |
JBE |
Jump if Below or Equal | CF=1 או ZF=1 (A ≤ B) |
קפיצות על סמך גדול/קטן – Signed¶
| פקודה | תנאי | הסבר |
|---|---|---|
JG |
Jump if Greater | ZF=0 ו־SF=OF |
JGE |
Jump if Greater or Equal | SF=OF |
JL |
Jump if Less | SF≠OF |
JLE |
Jump if Less or Equal | ZF=1 או SF≠OF |
קפיצות כלליות לפי דגלים¶
| פקודה | דגל | הסבר |
|---|---|---|
JC |
CF = 1 | Carry – הייתה נשיאה |
JNC |
CF = 0 | No Carry |
JO |
OF = 1 | Overflow – חריגה signed |
JNO |
OF = 0 | No Overflow |
JS |
SF = 1 | Sign – שלילי |
JNS |
SF = 0 | חיובי |
דוגמה מלאה – השוואת מספרים¶
mov ax, 10
mov bx, 20
cmp ax, bx ; משווה: 10 - 20
jl is_less ; אם ax < bx (signed)
je is_equal ; אם ax == bx
jg is_greater ; אם ax > bx (signed)
is_less:
; כאן נטפל במקרה ש־ax קטן מ־bx
jmp end
is_equal:
; כאן נטפל במקרה ששווים
jmp end
is_greater:
; כאן נטפל במקרה ש־ax גדול
jmp end
end:
דוגמה – לולאה עם cmp ו־jne¶
הלולאה תרוץ בדיוק 5 פעמים.
פקודה חשובה: TEST¶
ממש כמו AND, אך לא משנה ערכים, רק מעדכנת דגלים.