1.4 המחסנית פתרון
תרגיל 1 – PUSH / POP, PUSHA / POPA¶
stack_ex1.asm
IDEAL
MODEL small
STACK 100h
DATASEG
; אין נתונים קבועים
CODESEG
start:
mov ax, @data
mov ds, ax
; ----- חלק א: PUSH / POP -----
mov ax, 1111h
mov bx, 2222h
push ax
push bx
pop cx ; CX = 2222h
pop dx ; DX = 1111h
; הערה: אילו היינו כותבים כאן pop ax פעמיים ברצף
;‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
; ה‑CPU היה מושך «זבל» מה־Stack (Underflow).
; ----- חלק ב: PUSHA / POPA -----
pusha ; דוחף AX CX DX BX SP BP SI DI (16 בתים)
; … ניתן לשנות רגיסטרים כרצוננו …
popa ; משחזר את כולם
exit:
mov ax, 4C00h
int 21h
END start
תרגיל 2 – CALL ו‑RET¶
stack_ex2.asm
IDEAL
MODEL small
STACK 100h
CODESEG
start:
; כתובת הקפיצה תחזור לכאן
call HelloFunc
mov ax, 7777h ; ריצה נמשכת אחרי החזרה
; בשלב זה ה‑Stack נקי – כתובת החזרה כבר נשלפה ע\"י RET
exit:
mov ax, 4C00h
int 21h
; פונקציה ריקה
HelloFunc:
ret
END start
תרגיל 3 – פרמטרים באמצעות המחסנית¶
stack_ex3.asm
IDEAL
MODEL small
STACK 100h
CODESEG
start:
; --- Square(n) : n² ---
mov ax, 4
push ax
call Square ; AX = 16
; --- AddTwo(a,b) : a+b (cdecl) ---
push 2 ; param 2 (b)
push 5 ; param 1 (a)
call AddTwo
add sp, 4 ; caller cleans (cdecl). AX = 7
; --- AddTwoPascal(a,b) : a+b (pascal) ---
push 5 ; param 1
push 3 ; param 2
call AddTwoPascal ; callee cleans. AX = 8
exit:
mov ax, 4C00h
int 21h
; ---------- Functions ----------
Square: ; [BP+4] = n
push bp
mov bp, sp
mov ax, [bp+4]
mul ax ; AX = AX*AX
pop bp
ret
AddTwo: ; cdecl – caller cleans
push bp
mov bp, sp
mov ax, [bp+4]
add ax, [bp+6]
pop bp
ret
AddTwoPascal: ; pascal – callee cleans
push bp
mov bp, sp
mov ax, [bp+4]
add ax, [bp+6]
pop bp
ret 4 ; מנקה גם 2‑הפרמטרים
END start
תרגיל 4 – משתנים לוקליים עם BP¶
stack_ex4.asm
IDEAL
MODEL small
STACK 100h
CODESEG
start:
call LocalVarsFunc ; תוצאה חוזרת ב‑AX
exit:
mov ax, 4C00h
int 21h
; -------------------------------
; משריינת 4 בתים: var1=[BP‑2], var2=[BP‑4]
; מחזירה AX = var1² + var2
LocalVarsFunc:
push bp
mov bp, sp
sub sp, 4
mov word ptr [bp-2], 3 ; var1 = 3
mov word ptr [bp-4], 7 ; var2 = 7
mov ax, [bp-2]
mul ax ; AX = var1²
add ax, [bp-4] ; AX += var2
mov sp, bp
pop bp
ret
END start
תרגיל 5 – שמירת רגיסטרים¶
stack_ex5.asm
IDEAL
MODEL small
STACK 100h
CODESEG
start:
call SafeCalc
exit:
mov ax, 4C00h
int 21h
; SafeCalc משתמשת ב‑AX,BX ומבטיחה לא לשנות אותם
SafeCalc:
push bp
mov bp, sp
push ax
push bx
mov ax, 10
mov bx, 3
add ax, bx ; כל חישוב זמני
pop bx
pop ax
pop bp
ret
END start
תרגיל 6 – פונקציה מלאה (Multiply)¶
stack_ex6.asm
IDEAL
MODEL small
STACK 100h
DATASEG
Product dw ?
CODESEG
start:
push 3
push 5
call Multiply ; AX = 15
add sp, 4
mov Product, ax
exit:
mov ax, 4C00h
int 21h
Multiply: ; cdecl AX = a*b
push bp
mov bp, sp
mov ax, [bp+4]
mov bx, [bp+6]
mul bx ; DX:AX = AX*BX → AX התוצאה התחתונה
pop bp
ret
END start
תרגיל 7 – cdecl לעומת pascal¶
stack_ex7.asm
IDEAL
MODEL small
STACK 100h
CODESEG
start:
; --- cdecl ---
push 4
push 6
call MulCdecl
add sp, 4 ; caller cleans
; --- pascal ---
push 6
push 4
call MulPascal ; callee cleans
exit:
mov ax, 4C00h
int 21h
; ---------- Functions ----------
MulCdecl: ; AX = a*b (caller cleanup)
push bp
mov bp, sp
mov ax, [bp+4]
mov bx, [bp+6]
mul bx
pop bp
ret
MulPascal: ; AX = a*b (RET 4)
push bp
mov bp, sp
mov ax, [bp+4]
mov bx, [bp+6]
mul bx
pop bp
ret 4
END start
תרגיל 8 – אתגר¶
stack_ex8.asm
IDEAL
MODEL small
STACK 100h
DATASEG
ExprResult dw ? ; a + b*c
TempResult dw ? ; תוצאה זמנית
CODESEG
start:
; -------- a + b*c --------
push 3 ; c
push 2 ; b
push 1 ; a
call APlusBtimesC ; AX = 1 + 2*3 = 7
add sp, 6
mov ExprResult, ax
; -------- פונקציה עם Local tmp --------
push 9
call WithTemp
add sp, 2
mov TempResult, ax
exit:
mov ax, 4C00h
int 21h
; a + b*c (cdecl)
APlusBtimesC:
push bp
mov bp, sp
mov ax, [bp+6] ; b
mul word ptr [bp+4] ; b * c (c ב‑[bp+4])
add ax, [bp+8] ; + a (a ב‑[bp+8])
pop bp
ret
; WithTemp(n): מחזיר (n+1)*2 עם משתנה לוקלי
WithTemp:
push bp
mov bp, sp
sub sp, 2 ; tmp = [bp‑2]
mov ax, [bp+4]
inc ax
mov [bp-2], ax ; tmp = n+1
add ax, ax ; (n+1)*2 → AX
mov sp, bp
pop bp
ret
END start