اما در مورد پشته متاسفانه ديباگ محتواي پشته رانمايش نمي دهد. البته زياد هم مهم نيست كه ببينيم پشته را. فقط نظم را رعايت كنيم در ارسال و تحويل گيري از پشته كافيه.
من سعي كردم با ارسال رجيستري به پشته و بعد پيگيري با دستور e كه محتواي بايتها را نشان مي دهد در آخر قطعه دنبال پشته باشم ولي نتوانستم.
اموليتورها با شبيه سازي پشته محيط آموزشي خوبي فراهم مي كنند.
= = = == = = = = ==
اما سه نوع مقدار مي توانيم به رجيستر بدهيم. يكي همان عدد است كه با mov داديم به رجيستر در پست قبلي. ديگري قرار دادن مقدار رجيستر ديگر در يك رجيستر و ديگري از ram در رجيستر. به مثالهاي زير دقت كنيد:
کد:
mov ax,10 ; moves an immediate value into ax
mov bx,cx ; moves value from cx into bx
mov dx,Number ; moves the value of Number into dx
در كد بالا ، اولي را كه قبلا كار كرديم.
دومي مياد cx را در bx مي گذارد كه ساده است و زياد فرقي با اولي ندارد.
در سومي محتواي number را در dx ميگذارد. بعدا به طرز استفاده سومي خواهيم پرداخت.
بحث بعدي طرز صدا كردن وقفه هاست كه مثل تابع كارهايي را براي ما انجام مي دهند. هر وقفه مي تواند بيش از يك دستور اسمبلي باشد كه ما كاري باهاش نداريم و فقط كاري كه اين تابع بلده را ازش مي خواهيم. از كلمه int كه مخفف اينتراپت به معني وقفه است در اين مورد استفاده مي شود.
کد:
int 21h; Calls DOS service
int 10h ; Calls the Video BIOS interrupt
در كد بالا ما در اولي وقفه داس را صدا زده ايم و در دومي وقفه بيوس را ولي طرز صدا زدنشان فرقي ندارد. با كار آنها هم فعلا كار نداريم.
اما يك وقفه خاص مي تواند كارهاي متنوعي انجام دهد. مثلا همين int 21 دهها كار متنوع انجام مي دهد. براي اين كه يك كار خاص ازش بخواهيم بايد قبلش تنظيمش كنيم. مثل حالت كد زير:
کد:
mov ah,9 ; subroutine number 9
int 21h ; call the interrupt
در كد بالا با تنظيم ah داريم به وقفه 21 مي گوييم كه چه كاري ازش انتظار داريم. يعني اين دو دستور با هم باعث مي شوند كه وقفه 21 بياد و كار مثلا شماره 25 از مثلا 100 كار مختلف خود را انجام دهد و برود.
در انتهاي page 2 اين سايت يك برنامه گذاشته به عنوان اولين برنامه كه ما اجرا مي كنيم.
براي اجرا من در اديتورم كدش را مي نويسم و با پسوند asm ذخيره مي كنم و بعد با tasm و link به فايل اجرايي تبديل مي كنم. در اول تاپيك لينك دانلود اين دو هست.
حالا بايد مقداري شرح بدهيم قضايا را تا اين برنامه را درك شود.
اين برنامه از جهاتي براي ما خيلي مهم است.
يكي اين كه دستور end را دارد. كه عبارت است از :
کد:
mov ax,4c00h ; return to dos DOS
int 21h
اين نوع end براي فايل exe مناسب است. در اين دو خط اين جوري مي گوييم كه داريم از سرويس 4c از وقفه 21 استفاده مي كنيم براي اختتام برنامه.
در خط اول مي شد بنويسيم mov ah,4c و فرقي با اين نداره چون كه ax از ah و al تشكيل شده. و مي بينيد كه در كد بالا هم دو تا صفر در محل al هست.
زياد چيز پيچيده اي نيست اين دو خط كه بشه بيشتر توضيحش داد. فقط لازمه كه برنامه ما اين end را حتما داشته باشه. و بعد اين دو خط ديگه اجرا ادامه پيدا نمي كنه ، پس در جاي مناسب end را قرار بدهيد.
نكته بعدي برنامه ما اينه كه داره در قطعه اي داده ذخيره مي كنه. و داده ما hello world يعني يك رشته است. كل برنامه را حالا مي گذارم تا از خط اول روي آن بحث كنيم.
کد:
.model small
.stack
.data
Message db "Hello World!$" ; message to be display
.code
start proc
mov dx,OFFSET Message ; offset of Message is in DX
mov ax,SEG Message ; segment of Message is in AX
mov ds,ax ; DS:DX points to string
mov ah,9 ; function 9 - display string
int 21h ; call dos service
mov ax,4c00h ; return to dos DOS
int 21h
start endp
end start
خط اول آمده مدل برنامه را تعيين كرده. كه مدل ها ربط داره با تعداد قطعات و روش قرار گيري و چيزهاي ديگر كه بعدا بحث مي كنيم.
خط دوم پشته را تعريف كرده. چون عددي جلوي آن نيامده مقدار ديفالت براش قرار داده ميشه كه فكر كنم 1024 بايت است. بعدا نگاه مي كنم ميگم. فعلا مهم نيست. و كافي است اين مقدار. چون شما قراره كه هر چي در پشته مي گذاريد بعدا برداريد و پشته هر چه برنامه كار مي كنه نبايد با بي نظمي پر بشه.
بعد آمده نوشته data كه متغيري به نام Message تعريف كرده و بعدش db گذاشته و بعد مقدار آن را داده. و يك علامت $ هم در انتهايش گذاشته.
اين علامت دلار در اسمبلي نشانه اختتام رشته است .
ما در كدهايمان از وقفه اي استفاده مي كنيم كه به اين علامت دلار حساس است. بعدش هم هر چي بعد سمي كلون ; گذاشته كامنت است كه فقط شرح است و مي دانيد كه اجرا نميشه.
آن جا كه code نوشته تازه محلي است كه ما مي توانيم دستورات اسمبلي را بنويسيم.
آن دستور start proc را من اضافه كردم. در سايت نبود. همچنين start endp را. كلمه start را سايت براي اين انتخاب كرده چون اولين برنامه اي است كه داره عرضه ميشه و چيز خاصي نيست.
حالا چرا من اين دو خط را اضافه كردم؟ چون كه هر كامپايلري به راهنماهاي خاصي نياز داره و چون من با tasm كار مي كردم و ديدم اينها را مي خواهد اضافه كردم. شما شايد جور ديگه كار مي كنيد. اينها مهم نيست. چون همه راهنماها توسط كامپايلر برداشته ميشه و فقط كدهاي اسمبلي داخل فايل اجرايي اطراق مي كند.
شايد بپرسيد آن hello world!$ پس چي؟ يعني اگر فقط كدها اطراق مي كنند داخل فايل اجرايي ما اين رشته كجا مي رود.
جواب اين سئوال بحث جالبي دارد و آن بحث قطعه ها در فايل exe است. گفتيم كه در فايل com همه اجزا در يك قطعه جا مي گيرند ولي در فايل exe در قطعات مختلف مي توانند باشند. پس اين hello در قطعه خاصي قرار مي گيرد.
و قسمتي از كد ما هم حول همين محور ميچرخد.
بگذاريد واضح تر بگويم. اين دو خط كد برنامه را نگاه كنيد:
کد:
mov ah,9 ; function 9 - display string
int 21h ; call dos service
در اينجا باز وقفه اي احضار شده و در خط اولش هم شماره سرويس ذكر شده.
مواظب باشيد اين دو خط را با دو خط بعدي كه براي end برنامه كار مي كرد را اشتباه نكنيد.
حالا مي خواهيم راجع به سرويس 9 از وقفه 21 صحبت كنيم.
اين سرويس به ram در نقطه DS : DX نگاه مي كنه. Ds و dx شماره قطعه و آفست(آدرس بايت داخل قطعه) است. مثل همان كوچه و پلاك.
و چون اين سرويس به ds و dx نگاه مي كند بايد قبل آتش كردن اين سرويس بياييم dx و ds را تنظيم كنيم.
حالا روش تنظيم كردن dx و ds :
اولا بگم كه نميشده مستقيما به ds مقدار داد. چون يك جورهايي قابل انجام نيست اين كار و برمي گرده به طراحي اوليه. پس يك خط به كد ما اضافه شده سر همين.
يعني اول ريخته اند در ax و بعد از ax ريخته اند داخل ds . اين از اين.
فقط مي مونه اين كه آمده اند در اين ds:dx چي بريزند؟ جواب مختصر اين است مختصات Message را.
بعدا همه اينها را باز تمرين مي كنيم و شرح مي دهيم.
- - --
خط آخر برنامه يعني end start فقط كارش اينه كه بگه برنامه اصلي كدوم بود. ما فقط يك برنامه داريم و تابع نساختيم. تابع و برنامه اصلي دقيقا شبيه هم ساخته مي شوند. با همين proc و endp . پس end start داره ميگه كه start برنامه اصليه بوده.
براي اولين مثال ، مثال خوبي را انتخاب نكرده بود. سنگين بود. ولي اجزاي همين برنامه را در مثالهاي كوچك تر بعدا تمرين كنيم بهتر است.
= = = = = = = =
خوب. صفحه دوم هم تقريبا تمام شد. چند خط كوچك مونده كه در پست بعدي مي گويم.