פוסט: מוודא ריבוע קסם באסמבלי

;התוכנה הבודקת מערך דו מימדי של 3 על 3

;ומוודאת אם הוא ריבוע קסם

;אנו מניחים שהסכום של שורה אינו עולה על 255 (בית אחד) וזהו

.model small

.stack 100h

.data

index db 3; מסמן את מיקום תחילת המערך בזיכרון

sentinal db 0; הערך של השורה הראשונה והזקיף אליו משווים הכל

.code

mov ax,@data

mov ds, ax

; here your program starts

mov ah, 0

mov al, index

push ax

call mem; initializes a square beginning in index

mov ah, 0

mov al, index

push ax

call colomn ; checks equality of columns.

pop cx; בודק מה החזירה התת-תכנית ואם זה 0 היא מסיימת את התוכנה

cmp cl,0;

jz kill;

mov ah, 0

mov al, index

push ax

call rows ; checks for rows’ equality

pop cx; בודק מה החזירה התת-תכנית ואם זה 0 היא מסיימת את התוכנה

cmp cl,0;

jz kill;

mov ah, 0

mov al, index

push ax

call diagonal ; checks for diagonals’ equality

pop cx; בודק מה החזירה התת-תכנית ואם זה 0 היא מסיימת את התוכנה

cmp cl,0;

jz kill;

jmp good;

kill: mov al, 1 ; כדי להדליק נורה אחת

jmp e-n-d ; קופץ לסוף התוכנית

good: mov al,255; מדליק את כל הנורות כדי לאמר שזהו ריבוע קסם

jmp e-n-d ; קופץ לסוף התוכנית

e-n-d: out 2,al

; here you program ends

mov ah,4ch

int 21h

;——————————תת-תכנית לבדיקת העמודות———

colomn: mov al, 3 ; מונה ללולאה הקטנה

pop dx

pop bx

xor cl, cl ; מאפס

sum: add cl, [bx] ;מייצר זקיף לבדיקה

inc bl

dec al

jnz sum ; סוף לולאת הסכום

mov [1], cl ; מניח את הזקיף

mov ah, 2; לבדוק עוד שתי עמודות

xor cl, cl; מאפס את האוגר

loop: ; לולאה ראשית שמעבירה בין העמודות

cosum: add cl, [bx] ; לולאה שמחשבת את הסכום של העמודה

inc bl

inc al

cmp al, 3 ; בודק אם הוא עבר שלושה תאים

jnz cosum ; סוף הלולאה של סכום העמודה

cmp cl, sentinal ; בודק אם העמודה שווה לעמודה הראשונה

jnz sofnot ; לא שווה מסקנה שזה לא ריבוע קסם

dec ah ; מוריד את המונה כדי להראות כמה עמודות יש עוד לבדוק

jz sof ; כבר בדק שתי עמודות

xor cl, cl; מאפס את האוגר בשביל הבדיקה השנייה

xor al, al; מאפס את הקאונטר

jmp loop; עובר כדי לבדוק את עמודה 2

sofnot: mov cl, 0 ;מעביר שאין ריבוע קסם

push cx

push dx

jmp sofprog; מדלג על ההוראה הבאה על מנת לשמור את ערך האוגר נכון

sof: mov cl, 1; מעביר שיש ריבוע קסם

push cx

push dx

sofprog:

ret

;————————————————-

;——————- תת – תכנית לבדיקת השורות —-

rows: pop dx

pop bx

mov al, 3; מונה ללולאה הקטנה

mov ah, 3; מונה ללולאה הגדולה

xor cl,cl; מאפס את הצובר

rowsum: add cl,[bx] ; מחשב את הסכום של השורה

add bl, 3 ; קופץ לתא הבא בשורה לדוגמה מ- 1,1 ל- 2,1

dec al ; מוריד את המונה באחד

jnz rowsum ; קופץ חזרה עד שהוא מסיים את השורה

cmp cl, sentinal; משווה את השורה לעמודה הראשונה

jnz wrong; אין ריבוע קסם

dec ah ; מוריד אחד מהמונה של הלולאה הגדולה וכך מודיע שעבר לשורה הבאה

jz right; סיים את השורה השלישית

cmp ah, 1; בודק אם הוא בשורה השלישית

jz rowthee; סימן שזו כבר השורה השלישית

mov bl, index;

inc bl ; השורה הזו והשורה הקודמת מעבירות את התוכנה לתא הראשון בשורה השנייה

xor cl,cl ; לאפס את הצובר

mov al, 3; מחזיר את המונה ל – 3

jmp rowsum; חוזר חזרה ללולאה הראשית

rowthee: mov bl, index ; הלולאה מודיעה לתוכנית שזו כבר שורה שלישית

add bl, 2; תא ראשון בשורה השלישית

xor cl,cl ; לאפס את הצובר

mov al, 3; מחזיר את המונה ל – 3

jmp rowsum; חוזר חזרה ללולאה הראשית

wrong: mov cl, 0 ;מעביר שאין ריבוע קסם

push cx

push dx

jmp sofsub; קופץ לסוף התוכנה על מנת לשמור על ערכי המשתנה בוליאן

right: mov cl, 1; מעביר שיש ריבוע קסם

push cx

push dx

sofsub:

ret

;————————————————-

;——————–תת-תכנית לבדיקת אלכסונים —-

diagonal: pop dx

pop bx

mov al, 3; מונה של 3 כדי לספור תאים

mov ah, 2; מונה של הלולאה הראשית לדעת באיזה אלכסון הוא נמצא

xor cl,cl; מאפס את האוגר

jmp diag1sum; קופץ לחשב את האלכסון הראשון

diag2sum: add cl,[bx]; מחשב את האלכסון השני

add bl, 2; קופץ למשבצת הבאה באלכסון

dec al ; מוריד את המונה באחד

jnz diag2sum ; בודק אם הוא כבר עבר על שלושת התאים באלכסון השני

jmp compare; הולך להשוות את האלכסון השני לזקיף

diag1sum: add cl, [bx]; מחשב את האלכסון הראשון

add bl,4; קופץ למקום הבא באלכסון

dec al; מוריד את המונה באחד

jnz diag1sum; בודק אם הוא כבר עבר על שלושת התאים באלכסון הראשון

compare: cmp cl, sentinal; משווה את האלכסון לזקיף

jnz diagwrong; האלכסון לא שווה לזקיף משמע אין ריבוע קסם

dec ah ; מורידה את המונה באחד וככה מסמנת שבדקה כבר אלכסון

jz diagright; הת”ת בדקה את שני האלכסונים והם בסדר

mov bl, 5; מעביר את הנקודה של התחלת האלכסון השני לאוגר

xor cl, cl; מאפס את הצובר

mov al, 3; מחדש את המונה

jmp diag2sum; התכנית בדקה רק את האלכסון הראשון והיא קופצת כדי לחשב את השני

diagwrong: mov cl, 0 ;מעביר שאין ריבוע קסם

push cx

push dx

jmp diagsof; קופץ לסוף התכנה כדי לשמור על ערכי משתנה הבוליאן

diagright: mov cl, 1; מעביר שיש ריבוע קסם

push cx

push dx

diagsof:

ret

;——————————————————————-

;————————- תת – תכנית למילוי ריבוע קסם ————-

mem: pop dx

pop bx

mov [bx], 4

inc bl

mov [bx], 6

inc bl

mov [bx], 2

inc bl

mov [bx], 2

inc bl

mov [bx], 4

inc bl

mov [bx], 6

inc bl

mov [bx], 6

inc bl

mov [bx], 2

inc bl

mov [bx], 4

mov al, 0

out 2 ,al

push dx

ret

;—————————————————————-

end