دانلود مقاله آموزش اسمبلی

  • Code: # 17388

  • تعداد صفحات: 160
  • فرمت فایل: Word
  • سال: مشخص نشده
  • مقطع: مشخص نشده
  • دسته بندی: کامپیوتر - IT
قیمت جدید: ۲۵,۰۰۰ تومان
۳۰,۰۰۰ تومان
دانلود
  • خلاصه
  • فهرست
  • خلاصه دانلود مقاله آموزش اسمبلی

    برای یاد گرفتن اسمبلی باید با مبناهای عدد نویسی ، ساختمان داخلی کامپیوتر
    و برنامه نویسی آشنا باشیم .


    ما برنامه هایمان را مستقیما با اسمبلر Macro Assembler خواهیم نوشت و گاها از Debug
    استفاده خواهیم کرد .

    بعلاوه چون برنامه های حجیم نخواهیم نوشت قالب اکثر
    رنامه های ما COM.

    خواهد بود .


    برای شروع ابتدا نگاهی به حافظه میکنیم :

    حافظه و آدرس دهی

    هر کامپیوتر مبتنی بر 8086 دارای حداقل 640 کیلوبایت حافظه است .

    این 640
    کیلوبایت به قطعات 64 کیلوبایتی تقسیم شده و ما این قطعات را قطعه یا Segment
    مینامیم .

    هر سگمنت هم به خانه های تک بایتی دیگری تقسیم شده است .



    برای بدست آوردن مقدار یک بایت مشخص از حافظه ما باید عد مربوط به سگمنت و
    همچنین شماره آن بایت در سگمنت ( که آفست Offset نامیده میشود ) را بدانیم .


    مثلا اگر مقدار مورد نظر در قطعه 0030h(h( یعنی عدد در مبنای 16 است ) و آفست 13C4h
    باشد ما باید قطعه ای که شماره آن 0030h است را بیابیم و بعد در همان قطعه
    مقدار باین شماره 13C4 را بخوانیم .


    برای نمایش این حالت بین عدد سگمنت و آفست علامت (:) قرار میدهیم .

    یعنی
    ابتدا عدد مربوط به قطعه را نوشته و سپس عدد آفست را می آوریم :
    Segment:Offset

    مثال : 4D2F:َ9000 **
    همیشه در آدرس دهی ها از اعداد مبنای 16 استفاده میکنیم .



    | | |

    | CConvertional | 1 Segment=64K | | | | | Memory

    | | | | | |
    | | | |
    | | | |




    ثباتها Registers

    رجیسترها مکان هائی از CPU هستند که برای نگهداری داده ها (DATA) و کنترل اجرای
    برنامه بکار میروند .

    ما میتوانیم آنها را مقدار دهی کرده و یا بخوانیم و یا
    باتغییر محتوای آنها CPU را مجبور به انجام یک پروسه (رویه یا Procedure) کنیم

    دسته ای از رجیسترها که ما انها را ثباتهای همه کاره یا همه منظوره میخوانیم
    و شامل AX/BX/CX/DX هستند ، برای انتقال مقادیر بین رجیستر ها و CPU بکار میروند.
    این ثباتها را میتوانیم به هر نحوی تغییر دهیم و مقادیری را به آنهاارسال کنیم .



    ثباتهای دیگری هم که نام میبریم کاربردهای خاص خودشان را دارند و برای مقدار دهی
    آنها باید قواعد خاصی (که توضیح خواهیم داد) را بکار بریم .



    میکند عدد که در این ثبات وجود دارد شماره یک قطعه است و CPU برای یافتن DS : مخفف Data Segment .

    محل نگهداری متغییرها و ثابتهای برنامه را مشخص
    مقادیر لازم به آن قطعه مراجعه میکند .

    CS

    : مخفف Code Segment است و آدرس قطعه ای که برنامه در آن قرار گرفته را
    نشان میدهد .

    ES

    : این یک ثبات کمکی است و معمولا در آدرس دهی ها شماره قطعه را نگهداری
    میکند .

    DI

    DataIndex:Dبا DS/ESا مرتبط است و عدد آفست را نگهداری میکند .

    IP

    : این رجیستر معلوم میکند که برنامه در حال اجرائی که در CS قرار دارد از
    کدام بایت قطقه (یعنی کدام آفست ) شروع میشود .

    به همین دلیل همیشه این دو
    ثبات را با هم و بصورت CS:IP نشان میدهند.


    و ...



    تمام رجیسترهای فوق 16 بیتی (دوبایتی ) هستند و اعداد دوبایتی را نگهداری میکنند.


    ثباتهای همه منظوره به دو نیم ثبات تک بایتی تقسیم میشوند .

    بایت بالائی ب
    نماد H و بایت پائینی با نماد L نشان داده میشود .

    مثلا ثبات AX دارای دو نیم -
    ثبات AH/AL است :
    | AH - 8 Bit | AL -8 Bit |


    تمرین :
    برای دیدن رجیسترها در DOS، DEBUG، را اجرا کنید و فرمان R را صادر کنید :


    D:\MASM>DEBUG
    -R
    AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
    DS=17AA ES=17AA SS=17AA CS=17AA IP=0100 NV UP EI PL NZ NA PO NC
    17AA:0100 0F











    بیایید یک برنامه بنویسیم

    در این قسمت میخواهیم با استفاده از مطالبی که در بخشهای قبلی یاد گرفتیم
    برنامه ای بنویسیم که کامل و قابل استفاده باشد .

    با این برنامه میتوانیم
    فلاپی دیسکهای خودمان را با سرعت کپی کنیم !

    امروز برنامه را به شکلی مینویسیم که
    بتواند دیسکهای 1.44 را بوسیله درایو A کپی کند .

    بیشتر نیاز ما در کپی (تکثیر)
    دیسکها هم به همین شکل هست .

    با اینحال در قسمت بعدی نگارش (Version) جدیدتری از
    برنامه را مینویسیم و قابلیت تشخیص نوع دیسک و قابلیت مشخص کردن درایو را به آن
    اضافه میکنیم .


    بهترین کاری که میتوانیم بکنیم اینست که بتوانیم داده های خوانده شده از
    دیسک را در حافظه EMS بنویسیم (در این نسخه روی هارددیسک مینویسیم ) .

    وقتی که
    نحوه کار را حافظه گسترش یافته (Extended Memory) را هم یاد گرفتیم ، برنامه
    خود را کامل کرده و از آن بعنوان اولین دستختمان در برنامه نویسی اسمبلی لذت
    میبریم .


    لیست برنامه در زیر قرار دارد و توضیحات برنامه را روی آن میبینیم
    قبل از آن یاد آوری میکنم که هر دیسک HD َ1.44 دارای دو طرف و در هر طرف 80 شیار
    (Track) بوده و هر شیار هم به 18 بخش بنام قطاع (Sector) تقسیم میشود .

    برنامه
    ما باید محتوای تمام این قطاعها را خوانده و در فایلی روی دیسک سخت ذخیره کند.


    سپس همین داده ها را از فایل خوانده و مجددا روی دیسک جدید بنویسد.


    در این قسمت میخواهیم با استفاده از مطالبی که در بخشهای قبلی یاد گرفتیم برنامه ای بنویسیم که کامل و قابل استفاده باشد .

    با این برنامه میتوانیم فلاپی دیسکهای خودمان را با سرعت کپی کنیم !

    امروز برنامه را به شکلی مینویسیم که بتواند دیسکهای 1.44 را بوسیله درایو A کپی کند .

    بیشتر نیاز ما در کپی (تکثیر) دیسکها هم به همین شکل هست .

    با اینحال در قسمت بعدی نگارش (Version) جدیدتری از برنامه را مینویسیم و قابلیت تشخیص نوع دیسک و قابلیت مشخص کردن درایو را به آن اضافه میکنیم .

    بهترین کاری که میتوانیم بکنیم اینست که بتوانیم داده های خوانده شده از دیسک را در حافظه EMS بنویسیم (در این نسخه روی هارددیسک مینویسیم ) .

    وقتی که نحوه کار را حافظه گسترش یافته (Extended Memory) را هم یاد گرفتیم ، برنامه خود را کامل کرده و از آن بعنوان اولین دستختمان در برنامه نویسی اسمبلی لذت میبریم .

    لیست برنامه در زیر قرار دارد و توضیحات برنامه را روی آن میبینیم قبل از آن یاد آوری میکنم که هر دیسک HD َ1.44 دارای دو طرف و در هر طرف 80 شیار (Track) بوده و هر شیار هم به 18 بخش بنام قطاع (Sector) تقسیم میشود .

    برنامه ما باید محتوای تمام این قطاعها را خوانده و در فایلی روی دیسک سخت ذخیره کند.

    سپس همین داده ها را از فایل خوانده و مجددا روی دیسک جدید بنویسد.

    طول هر قطاع 512 بایت است EQU 512 SECTORSIZE تعداد شیار ها 80 شیار (79- 0-) است EQU 79 MAXTRACK هر دیسک دو طرف دارد EQU 2 NUMSIDES تعداد سکتور در هر شیار 18 تا است EQU 118 SECTOR_PER_TRACK E .MODEL SMALL .CODE ORG 100H START: JMP MAIN بافر برای ذخیره (0)BUF DB SECTORSIZE*SECTOR_PER_TRACK DUP داده ها .

    اندازه آن به اندازه بایتهای یک شیار است معرف رویه فعلی دیسک SIDE D DB 0 معرف تراک جاری TRACK DDB 0 هندل (مشخصه ) فایل HANDLE DW 0 اسم فایل برای دخیره موقت داده ها FILENAME DB 'C:TTEMP.$$$'/0 MSG1 DB 'ENTER A DISK INTO DRIVE A :THEN PRESS A KEY'/13/10/'$' MSG2 DB 'ENTER A NEW DISK INTO DRIVE A :THEN PRESS A KEY'/13/10/'$' رویه ReadTrack داده های یک شیار را بطور کامل میخواند .

    برای خواندن یک شیار کامل از Int 13h/Ah=02h استفاده کرده ایم .

    داده ها بعد از خوانده شدن در محلی که با ES:BX مشخص میشود ذخیره میشوند .

    (به مرجع اینتراپیتها مراجعه کنید) قبلا کار با این وقفه را توضیح داده ایم (برنامه Boots.asm را ببینید) READTRACK PROC ;READ A TRACK PUSH ES MOV AX/DS MOV ES/AX LEA BX/BUF MOV AH/2 MOV DL/0 ;DRIVE A: MOV DH/SIDE MOV CH/TRACK MOV CL/1 ;THE 1st SECTOR MOV AL/SECTOR_PER_TRACK INT 13H POP ES RET READTRACK ENDP این رویه داده های موجود در BUF را خوانده و در یک شیار کامل که با متغیر Track مشخص میشود مینویسد .

    برای اینکار از INT 13h/AH=03h استفاده شده است .

    آدرس متغیر BUF را باید در ES:BX قرار بدهیم .

    WRITETRACK PROC LEA BX/BUF PUSH ES MOV AX/DS MOV ES/AX شماره تابع برای نوشتن MOV AH/03 تعداد سکتورها برای نوشتن MOV AL/SECTOR_PER_TRACK شماره تراک MOV CH/TRACK شماره سکتور شروع MOV CL/1 رویه دیسک (طرف دیسک ) MOV DH/SIDE شماره درایو که اینجا A است MOV DL/0 INT 13H POP ES RET WRITETRACK ENDP این پروسیجر به اندازه یک تراک کامل از فایل خوانده و در متغیر BUF قرار میدهد READFILE PROC MOV BX/HANDLE اندازه یک تراک MOV CX/SECTORSIZE*SECTOR_PER_TRACK آدرس بافر برای ذخیره که DS:DX است LEA DX/BUF MOV AH/3FH INT 21H RET READFILE ENDP این پروسیجر کلیه داده های داخل BUF که به اندازه یک تراک کامل (18*512 بایت ) است را خوانده و در فایل مینویسد تا بعدا مجددا خوانده و روی دیسک جدید بنویسد WRITEFILE PROC MOV BX/HANDLE MOV CX/SECTORSIZE*SECTOR_PER_TRACK LEA DX/BUF MOV AH/40H INT 21H RET WRITEFILE ENDP منتظر میماند تا کلیدی فشرده شود WAIT PPROC تابع خواندن کلید MOV AH/0 INT 16H RET WAIT _ENDP این رویه فایل با هندل مشخص شده را میبندد CLOSEFILE PROC MOV AH/3EH MOV BX/HANDLE INT 21H RET CLOSEFILE ENDP شروع برنامه اصلی .

    MAIN: در این قسمت اعذم میکنیم که دیسکی را در درایو A قرار دهده و کلیدی را برنند .

    MOV AH/9 LEA DX/MSG1 INT 21H مکث برای دریافت کلید _CALL WAIT ساختن فایل برای ذخیره داده ها MOV AH/3CH LEA DX/FILENAME MOV CX/0 INT 21H MOV SIDE/0 MOV HANDLE/AX MOV TRACK/1 موتور دیسک خوان مدت زمانی لازم دارد تا به سرعت کافی برسد .

    بنا براین باید یک یا دو بار قبل از خواندن دیسک ، تابع خواندن را اجرا کنیم تا موتور دیسک در حالت مناسب قرار بگیرد.

    CALL READTRACK ; START UP THE CASSETTE-MOTOR COPY: MOV TRACK/0 COPYTRACK: خواندن شیار CALL READTRACK نوشتن داده های خوانده شده در دیسک CALL WRITEFILE شیار بعدی INC TRACK آیا شیار80 هستیم / CMP TRACK/80 نه ، شیار بعدی TRACKS َ; COPY 80 JNZ COPYTRACK طرف بعدی دیسک INC SIDE آیا طرف دوم دیسک هستیم ?

    CMP SIDE/1 نه ، پس ادامه بده JZ COPY وگر نه فایل را ببند CALL CLOSEFILE حالا اعلام میکنیم که دیسک جدید را در درایو A قرار دهد و کلیدی را بزند MOV AH/09H LEA DX/MSG2 INT 21H CALL WAIT_ MOV SIDE/0 همان فایل را برای خواندن باز میکنیم .

    وقتی که فایلی را میسازیم تنها میتوانیم در آن فایل بنویسیم .

    بنا براین برای خواندن از فایل ، باید آن را بسته و مجددا برای خواندن باز کنیم .

    LEA DX/FILENAME MOV AH/3DH MOV AL/0 INT 21H مشخصه فایل در Handle قرار میگیرد MOV HANDLE/AX MOV TRACK/1 MOV SIDE/0 اجرای تابع نوشتن برای راه اندازی موتور دیسک CALL WRITETRACK WRITE: MOV TRACK/0 WRITE_ON_TRACK: داده هارا از فایل بخوان CALL READFILE داده ها را روی شیار بنویس CALL WRITETRACK شیار بعدی INC TRACK آیا شیار 80 هستیم ?

    CMP TRACK/80 نه ، پس ادامه بده JNZ WRITE_ON_TRACK بله ، طرف بعدی دیسک INC SIDE آیا الان طرف دوم را هم خوانده ایم ?

    CMP SIDE/1 نه ، پس شیار بعدی را بنویس JZ WRITE بله ، فایل را ببند CALL CLOSEFILE فایلی که ساخته بودیم فضائی از دیسک سخت را اشغال کرده ، بنا براین بهتر است آن را با استفاده از وقفه 21h و تابع 3Ah حذف کنیم .

    LEA DX/FILENAME MOV AH/3AH INT 21H ;ERASE THE TEMPORARY FILE INT 20H END START تمام (: خوب ، رجیسترها را دیدیم و آشنائی کلی با آنها پیدا کردیم .

    حالا میخواهیم به رجیتسرها مقدار بدهیم و آنها را بخوانیم و ...

    .

    ما معمولا در ےزبانهای دیگر از علامت =(یا =ا:) برای مقدار دهی استفاده میکنیم ولی در زبان ےاسمبلی این کار ممکن نیست .

    در عوض از دستورالعمل MOV کمک میگیریم .

    با MOV میتوانیم داده ها را بین رجیسترها یا خانه های حافظه انتقال بدهیم .

    به این صورت MOV in_it/Value در اینجا In_it به معنای یک رجیستر، نام یک متغیر، یا آدرس یک مکان از حافظه است و Value هم یک مقدار عددی یا حرفی ، نام یک رجیستر و ...

    میباشد .

  • فهرست دانلود مقاله آموزش اسمبلی

تگ‌ها:

اسمبل - اسمبلی

  • ثبت سفارش
    عنوان محصول
    قیمت