1. مهمان گرامی، جهت ارسال پست، دانلود و سایر امکانات ویژه کاربران عضو، ثبت نام کنید.
    بستن اطلاعیه

آموزش اسمبلی(7)

شروع موضوع توسط hector2141 ‏15/10/12 در انجمن Assembly

  1. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,323
    تشکر شده:
    2,698
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    [​IMG]
    اگر با زبانهائی مثل Basicیا Pascalا برنامه نویسی کرده باشید حتما از دستور Goto هم استفاده کرده اید . بوسیله این فرمان ، ما میتوانستیم روال اجرای برنامه را به یک نقطه مشخص انتقال بدهیم بدون اینکه نیاز به برقراری شرط خاصی باشد .
    در زبان اسمبلی هم چنین دستوری داریم : دستورالعمل JMP (مخفف JUMP) .



    دستور JMP به این شکل استفاده میشود:
    برچسب JMP
    منظور از برچسب مکانی از برنامه است . در اسمبلی برای اینکه یک نقطه از برنامه را علامت بزنیم ، نام برچسب مورد نظر را مینویسیم و برای اینکه اسمبلر آن را با یک دستورالعمل اجرائی اشتباه نکند، کاراکتر (:) را در مقابل آن قرار میدهیم مانند: :Start
    سپس میتوانیم با دستور JMP به آنحا پرش کنیم .


    : Start

    :
    :

    Jmp Start
    دقت کنید که بعد از Start ی که در مقابل JMP نوشتیم علامت : قرار نداده ایم .
    این JMP ها از نوع JUMP NERA هستند و نوعی دیگر بنام JUMP FAR هم داریم که بزودی آن را هم یاد میگیریم .
    مثال : برنامه ای که در مثالهای قبل نوشتیم را در نظر بگیرید . اگر ما از روی دستورالعملهای برنامه با JMP پرشی انجام دهیم هیچکدام از آن کدها اجرا نخواهندشد:

    ۱] JMP Quit _
    2] mov ax/0E07h
    3] int 10h
    4] Quit :_
    5] int 20h

    برنامه از روی سطرهای ۲وَ۳ پرش خواهد کرد .
    ثبات پرچم (Flags)
    ثبات پرچم یک ثبات ۱۶ بیتی است که ۱یا ۰ا بودن بیتهای آن نشانه درست یا نادرست بودن یک شرط است . مثلا اگر با دستورالعمل خاصی (میخوانیم ) تست کنیم که آیا ثبات BX مقدار ۰ را دارد ، در این صورت بیت ۶ برابر ۰ میشود و … .
    از این ۱۶ بیت فقط ۹ بیت استفاده میشود که به شرح زیر هستند :

    ۱۶ ۱۵ ۱۴ ۱۳ ۱۲ ۱۱ ۱۰ ۹ ۸ ۷ ۶ ۵ ۴ ۳ ۲ ۱ ۰
    * * * * * O D I T S Z * A * P * C

    علامت * به معنای بی استفاده بودن است .
    ۱- پرچم نقلی یا (CF) . بیت ۰ در نتیجه اجرای وقفه ها یا بعضی اعمال حسابی تغییر میکند .
    ۲-پرچم توازن (ZF) . بر اساس یک عمل مقایسه ای یا حسابی تغییر میکند . اگر نتیجه یک عبارت ۰ باشد مقدار ۱ و اگر نتیجه ۱ باشد مقدار ۰ میگیرد.
    ۳-پرچم وقفه (IF) . اگر ۰ باشد هیچ وقفه ای نمیتواند اجرا شود و اگر ۱ باشد میتوان وقفه ها را فراخوانی کرد .
    و … . ۶ پرچم دیگر را فعلا لازم نداریم بنا براین توضیحی برای آنها ارائه نمیکنیم .

    دستور مقایسه ای CMP
    برای مقایسه مقادیراز دستور CMP (مخفف CoMPare) استفاده میکینم . این دستور مقدار داخل یک ثبات یا متغیر را با مقداری دیگر مقایسه کره و روی ثبات های CFو ZFو تاثیر میگذارد . بعد از مقایسه میتوانیم بر حسب وضعیت پرچمها پرش لازم را انجام دهیم .
    مثلا CMP BX/0 تست میکند که آیا مقدار BX برابر ۰ است یا نه . در صورتی که برابر ۰ باشد ،پرچم ZF برابر ۱ میشود .
    با همین دستور CMP میتوانیم کوچکتر،بزرگتر و …. را هم تست کنیم .

    پرشهای شرطی
    برای پرشهای شرطی از دستورهای زیر درست مثل JMP استفاده میکنیم .
    JE/JZ : اگر محتوای ZF صفر باشد جهش میکند . اگر دو مقداری که مقایسه کرده ایم برابر باشیند پرش انجام میشود.
    JNE/JNZ : برعکس JZو JEو هستند و اگر ZF یک باشد (بعبارتی دو مقداری که مقایسه کردیم برابر نباشند) جهش انجام میشود.
    JA/JNBE : اگر محتوای ثبات یا متغیری که مقایسه کرده ایم بزرگتر از عدد مورد نظر باشد پرش انجام میدهد .
    مثلا :

    mov bh/1
    cmp bh/10
    ja Dest

    مقدار BH برابر ۱ است و در سطر دوم تست آن را با ۱۰ مقایسه میکنیم . در سطر سوم چون BH بزرگتر از ۱ نیست ، پس پرش JA Dest انجام نمیشود .
    JAE/JNB : اگر بزرگتر یا مساوی باشد ، پرش انجام میشود.
    JB/JNAE: در صورتی که کوچکتر باشد پرش انجام میشود.
    JBE : در صورتی که کوچکتر یا مساوی باشد پرش انجام میشود .

    مثال :
    میخواهیم برنامه ای بنویسیم که تمام کاراکترهای بین ۱۲۸ تا ۲۵۵ را چاپ کند.


    ے تمام برنامه ساده و روشن است ولی در سطر آخر نکته جدیدی وجود دارد . بعد از END نام برچسب Start را آورده ایم . نکته ای که در نوشتن برنامه های اسمبلی باید مراعات کنیم اینست که : اگر از برچسبی در برنامه استفاده میکنیم ، اسمبلر باید یک برچسب را به عنوان نقطه آغاز کدبرنامه ببیند . به همین خاطر علاوه بر برچسب CHARS یک برچسب بنام Start هم در ابتدای برنامه تعریف کرده و برای اینکه اسمبلر بداند ما کدام برچسب را برای اینکار انتخاب کرده ایم ، نام آن را در مقابل END می آوریم ، یعنی END START .
    نکته دیگر اینکه ، در اسمبلر هر چیزی که بعد از کاراکتر (;) باشد ، توضیح (Comment) فرض شده و اصلا ترجمه نمیشود . (مثل REM در بیسیک و .. ) .
    هر comment باید در یک سطر جای داده شود و اگر از این مقدار بیشتر بود میتوانیم در سطر بعد
    هم یک کاراکتر (;) درج کرده و ادامه توضیحات را بعد از آن بیاوریم .

    . MODEL SMALL
    . CODE
    ORG 100H
    START :
    کاراکتر ۱۲۸ برای شروعMOV CH/128 CHARS : ;
    کداسکی را درAL قرار میدهیم تا چاپ شودMOV AL/CH ;
    سرویس ۰Eh برای چاپ کاراکترMOV AH/0EH ;
    اینتراپت 10 ; INT 10H
    یکواحد به CH اضافه کنINC CH ;
    مقایسه CH با 255 ; CMP CH/255
    اگر مساوی نباشد به CHARS پرش میکندJNZ CHARS ;
    INT 20H
    .END START ;پایان