8086 Assembler Tutorial for Beginners (Part 9)

The Stack

הדרכה בתכנות אסמבלר 8086 למתחילים (חלק 9)  

המחסנית

Stack is an area of memory for keeping temporary data. Stack is used by CALL instruction to keep return address for procedure, RET instruction gets this value from the stack and returns to that offset. Quite the same thing happens when INT instruction calls an interrupt, it stores in stack flag register, code segment and offset. IRET instruction is used to return from interrupt call.

מחסנית הוא אזור של הזיכרון (מקטע) לשמירת נתונים זמניים. המחסנית היא בשימוש על ידי פקודת CALL לשמירת את הכתובת החזרה מפרוצדורה, פקודת RET לוקחת הערך שנשמר במחסנית לחזרה לתוכנית הראשי למקום ממנו יצאה. אותו דבר קורה כאשר פקודת INT מבקשת ביצוע של פסיקה, במקרה זה שומרים במחסנית את אוגר הדגלים וערכי CS:IP . משתמשים בפקודת IRET לחזרה מביצוע פסיקה .

We can also use the stack to keep any other data,
there are two instructions that work with the stack:

PUSH - stores 16 bit value in the stack.

POP - gets 16 bit value from the stack.


Syntax for PUSH instruction:

אנחנו יכולים להשתמש במחסנית לשמירת כל נתון אחר דרך התוכנית שלנו,
יש שתי פקודות לעבודה עם המחסנית:

PUSH - דוחף (מאחסן) במחסנית ערך של 16 סיביות (מילה).

POP - מוציא (משיג) נתון בעל  16 סיביות (מילה). מהמחסנית.

התחביר של פקודת ה- PUSH:

PUSH REG     (אוגר רגיל 16 סיביות)
PUSH SREG             (אוגר סגמנט)
PUSH memory      (כתובת תא זיכרון)
PUSH immediate         (ערך מיידי)

REG: AX, BX, CX, DX, DI, SI, BP, SP.

SREG: DS, ES, SS, CS.

memory: [BX], [BX+SI+7], 16 bit variable, etc...

immediate: 5, -24, 3Fh, 10001101b, etc...

Syntax for POP instruction:

אוגר: AX, BX, CX, DX, DI, SI, BP, SP

אוגר סגמנט:
DS, ES, SS, CS

זיכרון:
BX], [BX+SI+7], 16 bit variable]

ערך מיידי:
5, 24-, 3Fh, 10001101b

התחביר של פקודת ה- POP:

POP REG  (אוגר רגיל 16 סיביות)
POP SREG          (אוגר סגמנט)
POP memory      (כתובת זיכרון)

REG: AX, BX, CX, DX, DI, SI, BP, SP.

SREG: DS, ES, SS, (except CS).

memory: [BX], [BX+SI+7], 16 bit variable, etc...
אוגר: AX, BX, CX, DX, DI, SI, BP, SP

אוגר סגמנט:
DS, ES, SS, CS

זיכרון:
BX], [BX+SI+7], 16 bit variable]
 
Notes:
  • PUSH and POP work with 16 bit values only!

     
  • PUSH immediate works only on 80186 CPU and later!


The stack uses LIFO (Last In First Out) algorithm,this means that if we push these values one by one into the stack:
1, 2, 3, 4, 5
the first value that we will get on pop will be 5, then 4, 3, 2, and only then 1.

הערות:
  • פקודות PUSH ו- POP עובדות עם ערכים של 16 סיביות בלבד (מילה).

     
  • פקודת PUSH עם ערך מיידי עובדת רק עם מעבד 80186 ומתקדמים ממנו !


המחסנית פועלת על פי אלגוריתם LIFO (אחרון שנכנס הוא הראשון לצאת), זאת אומרת שבדוגמה של הכנסת הנתונים הבאים למחסנית, אחד אחרי השני: ראשון 1, 2, 3, 4, ובסוף 5
הערך ראשון שנקבל ב-
POP יהיה 5, לאחר מכן 4, 3, 2, ורק בסוף 1.

It is very important to do equal number of PUSHs and POPs, otherwise the stack maybe corrupted and it will be impossible to return to operating system. As you already know we use RET instruction to return to operating system, so when program starts there is a return address in stack (generally it's 0000h).

PUSH and POP instruction are especially useful because we don't have too much registers to operate with, so here is a trick:
  • Store original value of the register in stack (using PUSH).

     
  • Use the register for any purpose.

     
  • Restore the original value of the register from stack (using POP).

Here is an example:

זה מאוד חשוב לבצע מספר שווה של פקודות PUSH ושל POP, אחרת מצביע המחסנית SP משנה את ערכו ויהיה בלתי אפשרי לחזור למערכת ההפעלה של המחשב. כפי שאתה כבר יודע אנחנו משתמשים בפקודת RET לחזרה למערכת ההפעלה (או לתוכנית הראשית), לכן כאשר מתחילה התוכנית היא שומרת במחסנית כתובת חזרה למערכת ההפעלה (בדרך כלל 0000h).

פקודות
PUSH ן- POP הם שימושיות במיוחד כי אין לנו יותר מידי אוגרים עבור התוכניות שלנו, לכן שי כאן פטנט:

  • אחסן הערך המקורי של אוגר במחסנית (השתמש בפקודת PUSH).

     

  • השתמש באוגר לכל מטרה.

     

  • החזר את הערך האוריגינלי (המקורי) מהמחסנית (השתמש ב- POP).

כאן דוגמה:

ORG    100h

MOV    AX, 1234h
PUSH   AX          ; store value of AX in stack.
                   ;        AX שמור במחסנית את הערך של

MOV    AX, 5678h   ; modify the AX value.
                   ;                 AX שנה את הערך של

POP    AX          ; restore the original value of AX.
                   ;         AX החזר את הערך שמקורי של

RET

END

Another use of the stack is for exchanging the values,here is an example: שימוש נוסף של המחסנית הוא להחלפת ערכים של אוגרים.   כאן דוגמה:


ORG    100h

MOV    AX, 1212h   ; store 1212h in AX.
                   ;
       AX טען ערך 1212 בתוך האוגר
MOV    BX, 3434h   ; store 3434h in BX
                   ;       BX
טען ערך 3434 בתוך האוגר


PUSH   AX          ; store value of AX in stack.
                   ;    AX שמור במחסנית את תוכן אוגר
PUSH   BX          ; store value of BX in stack.
                   ;    BX שמור במחסנית את תוכן אוגר

POP    AX          ; set AX to original value of BX.
                   ;    AX <- BX העתק הערך המקורי של
POP    BX          ; set BX to original value of AX.
                   ;    BX <- AX העתק הערך המקורי של

RET

END

The exchange happens because stack uses LIFO (Last In First Out) algorithm, so when we push 1212h and then 3434h, on pop we will first get 3434h and only after it 1212h.
 

The stack memory area is set by SS (Stack Segment) register, and SP (Stack Pointer) register. Generally operating system sets values of these registers on program start.

מתבצעת ההחלפה  כי המחסנית משתמשת באלגוריתם בשיטה ה- LIFO, וכאשר אנו דוחפים במחסנית את הערך 1212h ואז 3434h, בזמן ה-POP מקבלים קודם ה- 3434h ורק אחרי זה ה- 1212h.
 

תחום של מקטע המחסנית נקבע על ידי צמד האוגרים Stack Segment ו- Stack Pointer. בדרך כלל מערכת ההפעלה מגדירה את ערכי האוגרים האלה בהפעלת התוכנית.

"PUSH source" instruction does the following:
  • Subtract 2 from SP register.

     
  • Write the value of source to the address SS:SP.


"POP destination" instruction does the following:

  • Write the value at the address SS:SP to destination.

     
  • Add 2 to SP register.


The current address pointed by SS:SP is called the top of the stack.

For COM files stack segment is generally the code segment, and stack pointer is set to value of 0FFFEh. At the address SS:0FFFEh stored a return address for RET instruction that is executed in the end of the program.

You can visually see the stack operation by clicking on [Stack] button on emulator window. The top of the stack is marked with "<" sign.

הפקודה " מקור PUSH" מבצעת התהליך:

  • מחסיר 2 מאוגר SP

     

  • רושם את הערך של "מקור" בכתובת הזיכרון השייך למחסנית SS:SP.

 

הפקודה " יעד POP" מבצעת התהליך:

  • רושם את הערך שבכתובת הזיכרון השייך למחסנית SS:SP "ליעד".

     

  • מוסיף 2 לאוגר SP

הכתובת הנוכחית שמצביעים SS:SP נקרא החלק העליון של המחסנית.

לקבצים מסוג
COM, מקטע המחסנית היא בדרך כלל המקטע של התוכנית, ומצביע המחסנית הוגדר עם הערך 0FFFEh. בכתובת SS:0FFFEh נשמר כתובת חזרה לפקודת RET שמבוצע בסוף התוכנית.

בתוכנה של האמולטור ניתן להתבונן את פעולת המחסנית על ידי הקשה על כפתור [מחסנית] (
stack) בחלון של האמולטור. החלק העליון של המחסנית מודגש על ידי הסימן ">".

<<< to Part 8 <<   >> to Part 10 >>>

<<< לחלק 10 <<   >> לחלק 8 >>>