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

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

Code: #17388
تعداد صفحات
160
فرمت فایل
Word
سال
مشخص نشده
مقطع
مشخص نشده
دسته‌بندی

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

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


ما برنامه هایمان را مستقیما با اسمبلر 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 هم یک مقدار عددی یا حرفی ، نام یک رجیستر و ...

میباشد .

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

تگ‌ها