لینک پرداخت و دانلود *پایین مطلب*
فرمت فایل:Word (قابل ویرایش و آماده پرینت)
تعداد صفحه: 126
آموزش اسمبلی
برای یاد گرفتن اسمبلی باید با مبناهای عدد نویسی ، ساختمان داخلی کامپیوتر
و برنامه نویسی آشنا باشیم .
ما برنامه هایمان را مستقیما با اسمبلر 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) تقسیم میشود . برنامه
ما باید محتوای تمام این قطاعها را خوانده و در فایلی روی دیسک سخت ذخیره کند.
سپس همین داده ها را از فایل خوانده و مجددا روی دیسک جدید بنویسد.
طول هر قطاع 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 هم یک مقدار عددی یا حرفی ، نام یک رجیستر و ... میباشد .
ےمانند MOV AX/200 که عدد 200 دسیمال را به رجیستر AX منتقل میکند . (همیشه از
سمت راست به چپ ) .
در زبان اسمبلی ما میتوانیم با مبناهای 2وَ10وَ16 کار کنیم . اعداد به طور پیش
فرض مبنای 10 هستند . برای نشان دادن عدد هگزا (مبنای 16) در انتهای عدد یک
حرف H ( یا h ) و در انتهای اعداد باینری علامت (b) قرار میدهیم . مثلا برای نشان
دادن عدد AC1 مبنای 16 باید حتما آن را بصورت AC1h بنویسیم . به همین ترتیب عدد110b
همان عدد 6 خودمان است .
با این تفاسیر برای دادن مقدار 4Ch به رجیستر AX از دستور زیر استفاده میکنیم :
mov ax/4Ch
به همین شکل میتوانیم به نیم ثباتها هم مقدار بدهیم . مثلا میتوانیم برای مقدار
دهی AH بنویسیم : mov ah/20h . در این حالت مقدار نیم ثبات AL ثابت بوده و
محتوای AH برابر 20h میشود . چون نیم ثباتها تک بایتی هستند ما نمیتوانیم عدد
خارج از محدوده 0 تا 255 یا 128- تا 127 به آنها ارسال کنیم . در مورد اعداد منفی
هم باید از طریق تبدیل به مکمل دو عمل کنیم که به زودی آن روش را توضیح خواهیم
اد .
مثلا ما نمیتوانیم mov ah/100h را انجام دهیم چون 100h برابر 256 بوده و از محدوده
تعریف شده خارج است .
به همین شکل میتوانیم محتوای ثباتها را هم منتقل کنیم . مثلا برای کپی کردن محتوای
ثبات CXبه DX میتوانیم بنویسیم : mov dx/cx ، یعنی مقدار داخل Cx را به Dx کپی
کن .
ےباز هم باید به یک یا دوبایتی بودن ثباتها توجه کنیم . به عبارت دیگر ما
ےنمیتوانیم مقدار یک ثبات تک بایتی را به یک ثبات کامل دوبایتی منتقل کنیم .
مثلا عبارت mov DX/AL قابل قبول نیست چون AL یک بایتی بوده و DX دوبایتی است .
به عبارت ساده و کامل تر دو طرف عملوند MOV باید از نظر اندازه برابر باشند.
بنابر این :
MOV DL/AL
و MOV CL/BHوM درست ولی MOV DS/AH نادرست است .
به علاوه ما فقط میتوانیم ثباتهای همه منظوره AXتا DX را به این صورت مقدار دهی
ےکنیم . در صورتی که بخواهیم ثباتهائی مثل ..DS/ES/ را مقدار دهی کنیم باید از
رجیستر AX به عنوان واسطه استفاده کرده و مقدار را از طریق آن انتقال دهیم .
مثلا:
نمیتوانیم بنویسیم mov ds/20h
ولی میتوانیم داشته باشیم :
mov ax/20h
mov ds/ax
ےبه این ترتیب مقدار 20hبه DS انتقال پیدا میکند ( گرچه تغییر دادن DS ایده خوبی
نیست !)
ےحالا مطالب گفته شده را تمرین میکنیم . ما میتوانیم با DEBUG اسمبلی بنویسیم و
حتی برنامه های COM. درست کنیم . بنا براین در DOS، DEBUG، را اجرا کنید .
D:\LNG\ASM> DEBUG
ےیک خط تیره به صورت - ظاهر میشود . این خط تیره اعلان DEUBG برای وارد کردن
دستورات است .
حرف A (به معنی شروع وارد کردن دستورات اسمبلی ) را وارد کرده و Enter را بزنید .
ےعددی بصورت xxxx:0100 ظاهر میشود . این عدد برای شما (فعلا) مهم نیست ، پس به
آن توجه نکنید .
حالا میتوانید دستورات زیر را وارد کنید :
MOV AX/100
MOV BX/AX
MOV ES/AX
بعد از وارد کردن خط آخر یکبار دیگر کلید Enter را بزنید تا اعلان (-) دوباره ظاهر
شود .
در سطر اول ما عدد 100h ( پیش فرض اعداد در Debug هگزا است ) را به AX منتقل
کردیم . بعد مقدار AXبه BX و سپس مقدار AXبه ES منتقل شده . به این ترتیب همه
ثباتهای AX/BX/ES باید در نهایت برابر 100h باشند .
برای دیدن صحت این مطلب دستور T ( به معنای Trace) را وارد کنید .
با هر بار اجرای این دستور یکی از سطرهای برنامه اجرا میشود . بعلاوه شما میتوانید
محتوای رجیسترها را هم ببینید .
با اولین فرمان T ، سطر اول اجرا میشود . بازهم فرمان T را وارد کنید . الان مقدار100h
به BX داده شد و اگر به محتوای رجیستر AX توجه کنید خواهید دید که مقدار آن
(همانطور که انتظار داشتیم ) برابر 100h است . دوبار دیگر هم فرمان T را صادر
کنید و در نهایت مقدار ثباتهای AX/BX/ES را ببینید . هر سه ثبات (حالا) برابر 100h
هستند .
برای خارج شدن از Debug هم فرمان Q به معنی Quit را وارد کنید .
******
پس امروز یاد گرفتیم گه چطور مقادیر و داده ها را بین ثباتها منتقل کنیم .
خودتان همین تمرینات را با DEBUG انجام داده و در مورد MOV مطالعه کنید .
در قسمت بعد چیزهای بیشتری رو خواهیم خواند و یاد خواهیم گرفت.
تا اینجا یاد گرفتیم که چطور مقادیر را بین ثباتها منتقل کنیم : با فرمان MOV.
با همین دستور میتوانیم مقادیر را از محلهای حافظه خوانده یا در آنجا بنویسیم .
برای کار با حافظه دوحالت ممکن است وجود داشته باشد : 1
- آدرس مورد نظر در سگمنت جاری باشد . در برنامه های COM. کل برنامه (غالبا)
از یک سگمنت تشکیل میشود . 2
- آدرس مورد نظر خارج از سگمنت جاری باشد .
ثبات DS همیشه به قطعه ای اشاره میکند که داده های مورد نیاز برنامه در آن
هستند . این قطعه در برنامه های EXE. یک قطعه مستقل است ولی در برنامه های COM
. ، قطعه داده های و قطعه کد برنامه در یک سگمنت هستند . بنا براین مقدار
ثبات DS در یک برنامه COM. ثابت است .
در حالت کلی آدرس یک محل از حافظه بصورت DS:address مشخص میشود. DS حاوی
آدرس سگمنت داده ها بوده و address آفست را مشخص میکند .
چون همانطور که گفتیم DS در برنامه های COM. ثابت است ، پس در صورتی که آدرس
مورد نظر در همین قطعه باشد از نوشتن DS صرفنظر میکنیم .
به عنوان مثال اگر قطعه داده های برنامه ما 9000h باشد و ما بخواهیم آفست 24h
ام در همین قطعه را بدست بیاوریم ، میتوانیم از یکی از دو شکل زیر استفاده
کنیم :
DS:24h
or
24h
البته چون اسمبلر منظور ما از نوشتن عدد 24h را نخواهد فهمید شکل دوم یک خطای
هنگام ترجمه تولید خواهد کرد ولی ما روش صحیح را هم خواهیم گفت .
ما آدرس ها (یا اشاره گرها) را برای این میخواهیم که بتوانیم به یک خانه از
حافظه دسترسی پیدا کنیم . برای اینکه نشان بدهیم منظور ما از عدد مشخص شده ،
آدرس است نه خود عدد (مثل 24h در مثال قبلی ) آن عدد را داخل [] قرار میدهیم .
بنا براین :
mov ah/24h عدد 24h را به AX منتقل میکند ولی ....
mov ah/[24h] محتوای آفست 24h را به AX منتقل میکند .
در شکل دوم هر مقداری که در آفست 24h ام سگمنت جاری موجود باشد به ثبات Ah
منتقل میگردد.
به همین صورت میتوانیم یک مقدار را به یک خانه از حافظه منتقل کنیم : mov [24h]/ah
: محتوای ثبات AH را به آفست 24h ام منتقل میکند .
ے اگر آدرس مورد نظر خارج از محدوده سگمنت جاری بوده و در قطعه ای جدا قرار داشته
باشد ، میتوانیم از DSیا ESا (ترجیحا) برای دستیابی به حافظه استفاده کرد:
مثال : mov ax/9000h
mov ds/ax
mov ah/ds:[89h]
به این ترتیب ما به آفست 89h از سگمنت 9000h دسترسی پیدا میکنیم .
البته دستورات فوق مارا به مقصودمان میرسانند ولی ما نمیتوانیم به دلخواه خودمان DS
را تغییر دهیم چون همانطور که گفتیم DS به قطعه داده های برنامه اشاره میکند و
برنامه ، داده ها و مقادیر متغیر ها را از سگمنتی که با DS مشخص شده میخواند .
بنا براین ما نباید مقدار DS را تغییر بدهیم مگر اینکه آن را دوباره به حالت اول
برگردانیم . برای ذخیره و بازیابی محتوای رجیسترها، یک روش ساده و عمومی وجود
دارد که به زودی خواهیم گفت ولی در این مثال ما میتوانستیم مقدار قبلی DS را در
یک رجیستر دیگر مثل CX نگهداریم :
انتقال محتوای dsبه AX mov ax/ds
انتقال محتوای AXبه CX mov cx/ax
دادن مقدار9000hبه AX mov ax/9000h
انتقال محتوای AXبه DS mov ds/ax
خواندن آدرس mov ah/ds:[89h]
بازیابی مقدار DS mov ax/cx mov ds/ax
اگر بخواهیم آفست آدرس را با یک رجیستر مشخص کنیم باید به نکات زیر توجه
کنیم : 1
- اگر آدرس سگمنت با DS مشخص شده ، یا آدرس در سگمنت جاری باشد ، باید
مقدار آفست را در ثبات BX قرار دهیم . مثلا mov cx/[BX]یا mov cx/ds:[bx]ا .
2
- اگر از ES به عنوان مقدار سگمنت استفاده میشود باید از DI به عنوان آفست
استفاده کنیم مثل mov cx/es:[di] .
چون ما با برنامه های COM. سرو کار داریم ، پس از شکل اول و BX استفاده خواهیم
کرد .
دستیابی به مکانهای حافظه نکته های جالب دیگری هم دارد که در قسمت بعدی یاد
خواهیم گرفت .
دستیابی به مکانهای حافظه
وقتی که ما به روش گفته شده مقداری را از حافظه میخوانیم ، یک داده تک بایتی
از حافظه گرفته میشود . اما ممکن است بخواهیم که یک کلمه یا کلمه
مضاعف ( 4بایتی ) را بخوانیم یا بنویسیم . در این صورت میتوانیم از
پیشوند های زیر استفاده کنیم :
Byte Ptr
: برای دست یابی به یک بایت Word Ptr
: برای دستیابی به یک کلمه (2بایت ) Dword Ptr
: برای دست یابی به یک مقدار 4 بایتی
این پیشوند ها را باید قبل از آدرس مورد نظر قرار دهیم . به عنوان مثال برای
خواندن یک بایت از آفست 10h میتوانیم بنویسیم : mov al/byte ptr ds:[10h]
و برای خواندن دو بایت بصورت : mov ax/byte ptr ds:[10h] .
میتوانیم از همین روش استفاده کرده و مقداری را به حافظه انتقال دهیم . مثلا
میخواهیم یک کلمه دوبایتی را به آفست 34h (در سگمنت برنامه ) منتقل کنیم . کافی
است بنویسیم :
mov word ptr [34h]/1FCAh .
مثال :
mov bx/34h
mov ax/ds
mov cx/ax
mov ax/00h
mov ds/ax
mov ax/word ptr ds:[bx]
mov ax/cx
mov ds/ax
جمع و تفریق
بحث ما در مورد روشهای دستیابی و انتقال داده ها (فعلا) به پایان میرسد . حالا
میخواهیم ببینیم که چطور عمل جمع و تفریق ، و بعدا ضرب و ... ، را روی مقادیر
انجام دهیم .
این فقط قسمتی از متن مقاله است . جهت دریافت کل متن مقاله ، لطفا آن را خریداری نمایید
دانلود تحقیق کامل درمورد آموزش اسمبلی