10-12-2009, 18:44
|
מנהל
|
|
חבר מתאריך: 26.07.08
הודעות: 6,473
|
|
העתקת בלוק (מזה תסיק את משימה #1):
קוד:
FROM_ADDR EQU 40H
TO_ADDR EQU 50H
COPY_COUNT EQU 10H
MOV R0, #FROM_ADDR
MOV R1, #TO_ADDR
MOV R2, #COPY_COUNT
foreach: MOV A, @R0 ; Copy values in address pointed by R0 to register A
MOV @R1, A ; Copy the value in register A to the address pointed by R1
INC R0
INC R1
DJNZ R2, foreach
END
מקוה שלא טעיתי, מזמן לא נגעתי.
הסבר:
בראש התוכנית אנו מגדירים קבועים כדי שהתכנית תהיה מובנת ככל האפשר. הרי, אם היינו משתמשים במספרים במקום בקבועים, היה קשה יותר להבין מה התוכנית עושה (נכון בעיקר לתוכניות גדולות).
לאחר מכן מעבירים את ערכי הקבועים לאוגרים R0,R1,R2 כדי שנבצע את המטרה שלנו בקלות. (עדיף, לדוגמא, מאשר להעביר לכתובת בזיכרון ה-RAM או עדיף על שימוש בפחות אוגרים).
לאחר מכן הגדרתי תוית ששמה foreach, שמשמעותה זה "על כל העתקה יש לבצע את הקוד הבא, שקיים עד לתנאי המיוצג במילה DJNZ". שים לב שזה רק המשמעות שלה - זה לא שהיא מבצעת את זה, אלא הבלוק שנמצא אחרי מבצע זאת. התוית foreach לא תהיה קיימת בזיכרון ה-EPROM (כלומר לא תהיה קיימת בתוכנית), היא באה לייצג כתובת בזיכרון.
הייתי יכול להגדיר תוית עם שם אחר לגמרי (כמו ABCDEFG) - אבל בחרתי בשם הזה. תשתדל לבחור תויות סמנטיות ככל האפשר.
בפקודת ה-MOV הראשונה שלאחר-מכן, אנו מעבירים את הערך שבכתובת המוצבעת ע"י אוגר R0 אל האוגר A.
בפקודת ה-MOV הבאה אנו מעבירים את הערך שבאוגר A אל הכתובת שמוצבעת ע"י האוגר R1.
אנו עושים זאת דרך אוגר A, ולא בצורה ישירה כמו:
כי אנחנו פשוט לא יכולים לעשות זאת - המעבד יכול לבצע פעולות העברה אך ורק דרך האוגר A. האוגר A הוא אוגר מרכזי שדרכו עובר כל המידע, וכל החישובים מתבצעים דרכו.
לאחר מכן 2 פקודות INC להגדלת הערך שבאוגרים R0 ו-R1, על מנת שנוכל להתקדם לכתובת אחת מעלה. (כדי שבאיטרציה הבאה נעתיק את הערכים מהכתובות האלו)
לבסוף תנאי DJNZ, שזה ראשי תיבות של Decrement Jump No Zero.
בתנאי זה אנחנו מורידים את ערכו של R2 ב-1, ולאחר-מכן שואלים "האם R2 שונה מ-0?".
אם התשובה היא כן: אז יש לקפוץ מעלה לתוית foreach. (במקרה שלנו הקפיצה היא מעלה, אך אם התוית foreach הייתה למטה - אז גם היה אפשר לקפוץ אליה)
אם התשובה היא לא: אז המעבד ממשיך להריץ את הפקודות הבאות, שנמצאות אחרי DJNZ.
לאחר מכן פקודת END המסיימת את ריצת המעבד.
נערך לאחרונה ע"י dorM בתאריך 10-12-2009 בשעה 18:53.
|