close
دانلود فیلم
اسمبلر

دستورات push و pop

دستورات push و pop دستورات پايه برای استفاده از پشته هستند. برنامه نويس اسمبلی از طريق دستورات زير می تواند داده های خود را در پشته قراردهد و يا از پشته بردارد. فرم کلی دستورات به صورت زير است:

push mem/reg
pop   mem/reg

push عملوند خود را به پشته اضافه می کند و دستور pop مقداری را از پشته حذف می کند و در عملوند خود قرار می دهد. داده ای که برداشته می شود هميشه آخرين داده ای است که اضافه شده است.

عملوند دستورات push و pop نمی توانند فوری يا ثبات های CS و IP و flag باشند.


مثال 1. دستورات زير يک کلمه را در پشته قرار می دهد.

mov AX, 12
push AX

مثال 2. دستورات زير محتوای دو متغير Value و Count را با هم تعويض می نمايد.

push Value
push Count
pop Value
pop Count

مثال 3. به کمک دستورات پشته می توان محتوای يک ثبات سگمنت را در ديگری کپی کرد.

push DS
pop CS

مثال 4. مقدار نهائی AX برابر با 1234h است. ابتدا در AX عدد 1234h ذخيره می شود سپس وقفه فراخوانی می شود. مقدار AX از پشته بازيابی می شود.

mov AX,1234H
push AX
mov AH,09
int 21H
pop AX

ماکرو مجموعه ای از دستورات است که مشابه زيربرنامه يکبار نوشته می شود و چندين بار استفاده می شود.


ماکرو (macro) نام مخففی برای مجموعه ای از دستورالعمل ها، راهنماها يا ماکروهای ديگر است که يکبار نوشته می شود و به هر تعداد دفعات لازم قابل استفاده است.

اسمبلر هنگام ترجمه برنامه در مواجهه با نام ماکرو دستورات معادل را قرار می دهد.

STC
CLC
CMC
STI
CLI
NOP


STC

دستورالعمل (set carry) stc باعث يک شدن فلگ Carry می شود. فرم کلی آن به صورت زير است:

stc

دستورالعمل stc روی فلگ های ديگر تاثير ندارد.


CLC

دستورالعمل (clear carry) clc باعث صفر شدن فلگ Carry می شود. فرم کلی آن به صورت زير است:

clc

دستورالعمل clc روی فلگ های ديگر تاثير ندارد.


CMC

دستورالعمل (compliment carry) cmc باعث عکس شدن فلگ Carry می شود. يعنی اگر صفر باشد آنرا يک و اگر يک باشد آنرا صفر می کند. فرم کلی آن به صورت زير است:

cmc

دستورالعمل cmc روی فلگ های ديگر تاثير ندارد.


STI

دستورالعمل (set interrupt) sti باعث يک شدن فلگ Interrupt می شود. فرم کلی آن به صورت زير است:

sti

دستورالعمل sti روی فلگ های ديگر تاثير ندارد.


CLI

دستورالعمل (clear interrupt) cli باعث صفر شدن فلگ Interrupt می شود. فرم کلی آن به صورت زير است:

cli

دستورالعمل cli روی فلگ های ديگر تاثير ندارد.


NOP

دستورالعمل (no operation) nop هيچ عملی انجام نمی دهد.

دستورات چرخش رشته های بيتی را به صورت دايره ای حرکت می دهد اين دستورات مشابه شيفت عمل می کنند با اين تفاوت که بيتی که از يک طرف از داده خارج می شود به طور دوار از جهت ديگر وارد آن می شود. پردازنده 8086 چهار دستورالعمل چرخش (rol ، ror ، rcl و rcr) دارد.

ROL
ROR
RCL
RCR


ROL

دستورالعمل (rotate left) rol بيت های عملوند خود را به سمت چپ چرخش می دهد. فرم کلی آن به صورت زير است:

rol dest, count

دستورالعمل rol بيت های عملوند مقصد خود را به تعداد count به سمت چپ چرخش می دهد. بيتی که از سمت چپ خارج می شود از سمت راست وارد عملوند می شود.با ارزش ترين بيت عدد در فلگ carry کپی می شود.

عملوند اول عملوند مقصد است و عملوند دوم تعداد شيفت ها را مشخص می کند و می تواند عدد 1 يا برای تعداد بيشتر ثبات CL باشد. نوشتن عدد فوری بيشتر از 1 مستقيما در دستور غير مجاز است.

دستورالعمل rol به شکل های زير می تواند استفاده شود:

rol register, 1
rol memory, 1
rol register, CL
rol memory, CL

دستورالعمل rol بيت های فلگ را به صورت زير تغيير می دهد:

• فلگ carry حاوی آخرين با ارزش ترين بيت عملوند می شود.
• اگر تعداد چرخش يکبار باشد و علامت عدد بعد از چرخش تغيير کند فلگ overflow يک می شود. برای چرخش بيشتر از يکبار نامعين است.
• روی فلگ های Sign ، Zero ، Parity و Auxiliary carry تاثير ندارد. اگر نيازداريد مقدار اين فلگ ها را بعد از عمل چرخش بدانيد نتيجه را با صفر مقايسه کنيد تا اين فلگ ها تنظيم شوند.


مثال.

mov AX, C123h
mov CL,3
rol AX, CL    ;AX = 091Eh, CF = 0


ROR

دستورالعمل (rotate right) ror بيت های عملوند خود را به سمت راست چرخش می دهد. فرم کلی آن به صورت زير است:

ror dest, count

دستورالعمل ror بيت های عملوند مقصد خود را به تعداد count به سمت راست چرخش می دهد. بيتی که از سمت راست خارج می شود از سمت چپ وارد عملوند می شود.

مشابه دستورالعمل rol عملوند دستورالعمل ror می تواند ثبات يا حافظه باشد. تعداد چرخش عدد 1 يا ثبات CL است.

کم ارزش ترين بيت عملوند وارد فلگ carry می شود. بقيه فلگ ها مشابه دستورالعمل rol تاثير می پذيرند.


مثال.

mov AX, C123h
mov Cl,2
ror AX, CL     ;AX = F048h, CF = 1


RCL

دستورالعمل (rotate through carry left) rcl همانطور که از نامش پيدا است، بيت ها را از طريق فلگ carry به سمت چپ می چرخاند. شکل کلی آن به صورت زير است:

rcl dest, count

دستورالعمل rcl محتوای فلگ Carry را از سمت راست وارد عملوند مقصد می کند، سپس بيت های عملوند را به سمت چپ شيفت می دهد و آخرين بيت سمت چپ را وارد فلگ Carry می شود.

دستورالعمل rcl مشابه rol استفاده می شود و روی فلگ ها تاثير می گذارد.


RCR

دستورالعمل (rotate through carry right) rcr بيت های داده را از طريق فلگ carry به سمت راست می چرخاند. شکل کلی آن به صورت زير است:

rcr dest, count

دستورالعمل rcr محتوای فلگ Carry را از سمت چپ وارد عملوند مقصد می کند، سپس بيت های عملوند را به سمت راست شيفت می دهد و آخرين بيت سمت راست را وارد فلگ Carry می شود.

دستورالعمل rcr مشابه ror استفاده می شود و روی فلگ ها تاثير می گذارد.

دستورات شیفت يک رشته بیتی را به سمت راست يا چپ حرکت می دهند. توسط اين دستورات می توان روی بيت های داده کار کرد؛ داده را ادغام يا جدا کرد و عمليات محاسباتی را انجام داد. ريزپردازنده 8086 سه دستورالعمل شيفت (shl/sal، shr و sar) دارد. بخش زير هر يک از اين دستورالعمل ها را شرح می دهد.

SHL/SAL
SHR
SAR
کاربردهای شيفت


عمل شيفت بيت های داده را حرکت می دهد. حرکت بيت ها می تواند به سمت چپ (به سمت بيت های با ارزش) يا راست (به سمت بيت های کم ارزش) باشد. فلگ Carry معمولا آخرین بيت شیفت داده شده که از عملوند خارج می شود را می گيرد.

دو نوع شيفت وجود دارد: شيفت منطقی و شيفت رياضی. شيفت منطقی ساده ترين شيفت است که به طريق ساده ای بيت ها را شيفت می دهد. در شيفت رياضی علامت عدد حفظ می شود.


مثال. يک عدد شيفت داده شده يک بايتی نشان داده شده است.

Shift Example

توجه کنيد که بيت های جديدی که وارد می شوند هميشه صفر هستند.


SHL/SAL

دستورالعمل (shift left) shl يا (shift arithmetic left) sal بيت های داده را به سمت چپ حرکت می دهد. فرم کلی آنها به صورت زير است:

shl dest, count
sal dest, count

shl و sal معادل هستند و يک دستورالعمل را نشان می دهند يعنی کد يکسانی دارند. اين دستورالعمل ها هر بيت عملوند مقصد را به سمت چپ عدد به تعداد عملوند count حرکت می دهند. از سمت راست عدد 0 وارد عدد می شود و آخرين بيتی که از سمت چپ خارج می شود وارد فلگ carry می شود.

عملوند اول مقداری است که شيفت داده می شود و عملوند مقصد است. count تعداد شيفت ها را مشخص می کند و می تواند عدد 1 يا برای تعداد شيفت های بالاتر ثبات CL باشد. نوشتن تعداد شيفت بيشتر از 1 مستقيما در دستور غير مجاز است.

دستورالعمل shl/sal می تواند به صورت های زير بکار رود:

shl register, 1
shl memory, 1
shl register, CL
shl memory, CL

دستورالعمل shl/sal به صورت زير روی فلگ تاثير می گذارد:

• اگر تعداد شيفت صفر باشد فلگ ها تغييری نمی کنند.
• فلگ carry آخرين بيت خارج شده از سمت چپ عملوند را نگه می دارد.
• فلگ overflow در يک بيت شيفت يک می شود اگر دو بيت آخرعملوند متفاوت باشند. به عبارت ديگر بعد از عمل شيفت بيت علامت عدد تغيير کند. برای شيفت های بيشتر از يکبار نامعين است.
• فلگ zero، sign و parity با توجه به نتيجه تغيير می کنند.
• فلگ Auxilury Carry نامعين است.


مثال.

mov AX, 4123h
shl AX, 1    ; shift 1 bit to left, ax = 8246H, CF = 0


SHR

دستورالعمل (shift right) shr بيت های داده را به سمت راست حرکت می دهد. فرم کلی آنها به صورت زير است:

shr dest, count

دستورالعمل shr کليه بيت های عملوند مقصد را به تعداد count به سمت راست شيفت منطقی می دهد. از سمت چپ صفر وارد عملوند می شود و آخرين بيتی که از سمت راست خارج می شود وارد فلگ Carry می شود.

دستورالعمل shr مانند shl استفاده می شود؛ عملوند آن می تواند ثبات يا مکانی از حافظه باشد و تعداد شيفت ها می تواند عدد 1 يا ثبات CL باشد.

دستورالعمل shr فلگ ها را به صورت زير تنظيم می کند:

• اگر تعداد شيفت صفر باشد فلگ ها تغييری نمی کنند.
• فلگ carry آخرين بيت خارج شده از سمت راست عملوند را نگه می دارد.
• در يک بيت شيفت فلگ overflow يک می شود اگر دو بيت آخرعملوند متفاوت باشند. به عبارت ديگر اگر بعد از عمل شيفت بيت علامت عدد تغيير کند. برای شيفت های بيشتر از يکبار نامعين است.
• فلگ zero، sign و parity با توجه به نتيجه تغيير می کنند.
• فلگ Auxilury Carry نامعين است.


مثال.

mov AX, C1A5h
mov CL,3
shr AX, CL    ; shift 3 bit to right, ax = 1834h, CF = 1


SAR

دستورالعمل (shift arithmetic right) sar مانند دستورالعمل shr است با اين تفاوت که علامت عملوند تغيير را نمی دهد. فرم کلی آن به صورت زير است:

sar dest, count

اين شيفت برای اعداد علامتدار طراحی شده است و بيت های عملوند مقصد را به سمت راست شيفت رياضی می دهد و بيت علامت را در خودش کپی می کند.

دستورالعمل sar مشابه دستورالعمل shr بکار می رود و به همان صورت روی فلگ ها تاثير می گذارد.


مثال.

mov AX, C1A5h
sar AX, 1    ; shift 1 bit to right, ax = E0D2h, CF = 1


کاربردهای شيفت

مثال. فرض کنيد می خواهيد دو نيبل پائينی ثبات های AL و AH را با هم به صورت زير ترکيب کنيد. کد زير اين کار را انجام می دهد.

mov CL, 4
shl AH, CL
and AL, 0Fh
or AL, AH

مثال. فرض کنيد می خواهيد دو نيبل ثبات AL را از هم جدا کرده و نيمه سمت چپ را در ثبات AH و نيمه سمت راست را در ثبات AL به صورت زير قرار دهيد. کدهای زير اين عمل را انجام می دهد.

mov AH, AL
mov CL, 4
shr AH, CL
and AL, 0Fh

مثال. هر شيفت به چپ باعث دو برابر شدن عملوند می شود که سرعت بيشتری نسبت به عمل mul دارد. دستورالعمل های shl/sal برای ضرب مقادير علامت دار يا بدون علامت در توان های 2 استفاده می شود. دستور زير مقدار ثبات AX را در عدد 4 ضرب می کند.

mov CL,2
shl AX, CL

مثال. برای محاسبه 10×AX می توانيد به روش زير از دستورشيفت چپ استفاده کنيد (با توجه به اينکه 10×AX=8×AX + 2×AX).

shl AX, 1
mov BX, AX
shl AX, 1
shl AX, 1
add AX, BX

مثال. کدهای زير حاصلضرب AX×7 را محاسبه می کنند (با توجه به اينکه ax×7 = (ax×8)-ax ).

mov BX, AX
shl AX, 1
shl AX, 1
shl AX, 1
sub AX, BX

مثال. چون يک شيفت منطقی به سمت راست مقدار يک عدد صحيح بدون علامت را نصف می کند می توان برای تقسيم بر توان های 2 از آن استفاده کرد. دستورات زير خارج قسمت مقدار ثبات AX بر 8 را محاسبه می کنند.

mov CL,3
shr AX, CL

مثال. برای انجام تقسيم علامتدار بر توان های 2 از شيفت رياضی راست استفاده می شود. دستور زير مقدار ثبات AX را بر عدد 32 تقسيم می کند.

mov CL,5
sar AX, CL

مثال. توجه کنيد اگر عملوند منفی باشد نتيجه دو دستور sar و idiv متفاوت می شود. به دستورات زير دقت کنيد.

mov ax, -15
cwd
mov bx, 2
idiv            ;خارج قسمت 7- مي شود

mov ax, -15
sar ax, 1    ;خارج قسمت 8- مي شود

مثال. از شيفت رياضی راست می توانيد برای گسترش رياضی یک عدد علامتدار استفاده کنيد. به کدهای زير دقت کنيد.

; CBW معادل دستور:
mov AH, AL
mov CL, 7
sar AH, CL

; CWD معادل دستور:
mov DX, AX
mov CL, 15
sar DX, CL

البته وقتی يک دستور cbw يا cwd برای گسترش وجود دارد کسی از دو دستور استفاده نمی کند، ولی دستور شيفت اجازه می دهد که مقدار يک ثبات را در هر ثبات ديگرهم اندازه ای به طور رياضی گسترش دهيد:

; DX:BX به BX گسترش رياضی:
mov DX, BX
mov CL, 15
sar DX, CL

دستورالعمل های انتقال داده مقادير را از يک محل به محل ديگر کپی می کنند.

MOV
XCHG
LEA


MOV

ساده ترين دستورالعمل mov است که دارای دو عملوند است. اين دستورالعمل محتوای دومين عملوند خود را در اولين کپی می کند. فرم کلی آن به صورت زير است:

mov Dest, Source

دستور mov يک کپی از Source را گرفته و آنرا در Dest ذخيره می کند. محتوای Source بعد از اجرای دستور تغيير نمی کند ولی مقدار قبلی Dest رونويسی می شود.

دستور mov مشابه دستور انتساب در زبان های سطح بالا است ( Dest := Source; در زبان Pascal يا Dest=Source; در زبان C).

با توجه به نوع عملوندها، انواع مختلفی از دستورالعمل mov را می توان داشت. متداولترین آنها عبارتند از:

mov register, register
mov memory, register
mov register, memory
mov memory, immediate data
mov register, immediate data
mov AX/AL, memory
mov memory, AX/AL
mov segment register, memory 16
mov segment register, register 16
mov register 16, segment register
mov memory 16, segment register

چند موضوع مهم درباره دستور mov را باید همواره بخاطر داشت:

1. انتقال حافظه به حافظه وجود ندارد. يعنی هردو عملوند همزمان نمی توانند عملوند حافظه ای باشند.
2. عملوندها می تواند از نوع بايت يا کلمه باشند. اما هردو عملوند حتما بايد هم اندازه باشند (برای مثال دستور mov AX,BL اشتباه است). اين برای عملوند های حافظه و ثبات هم باید رعایت شود (اگر متغيری را يک بايتی تعريف کنيد و آنرا در ثبات AX منتقل کنيد اسمبلر پيغام خطا صادر می کند).
3. با اين دستور نمی توان يک داده فوری را در يک ثبات سگمنت منتقل کرد.
4. هر دو عملوند نمی توانند ثبات سگمنت باشند.
5. گونه هائی از دستور mov سريع تر و کوتاهتراز بقيه هستند. برای مثال هر دو دستور mov ax, mem و mov reg, mem داده ای را از حافظه به ثبات کپی می کنند اما دستورالعمل اول کوتاهتر و سريع تر از دومی است.
6. می توان يک مقدار فوری را در يک محل حافظه منتقل کرد. در اين حالت داده فوری به اندازه عملوند مقصد گسترش داده می شود (مگراينکه بزرگتر از مقصد باشد که خطا صادر می شود). البته اسمبلر نمی تواند اندازه عملوند حافظه را تعيين کند مگر اينکه عملوند حافظه ای به صورت يک متغير در برنامه اعلان شده باشد. برای حل اين مشکل از عملگر های byte ptr و word ptr برای تعيين اندازه عملوند حافظه ای می توان استفاده کرد.


مثال. دستور زيرداده فوری 10h را به اندازه يک کلمه گسترش داده و در محلی که BX به آن اشاره می کند ذخيره می کند.

mov word ptr [bx], 10h

مثال. دستورات زير داده فوری 40h را در ثبات سگمنت ES ذخيره می کند. ثبات AX به عنوان واسطه بکار رفته است. هر کدام از ثبات همه منظوره را می توان به جای AX بکار برد.

mov AX, 40h
mov ES, AX


دستور mov روی هيچکدام از فلگ ها تاثيری ندارد.


XCHG

دستورالعمل xchg محتوای دو عملوند خود را جابجا می کند. فرم کلی آن به صورت زير است:

xchg Operand1, Operand2

مقدار هردو عملوند در اثر اجرا تغيير می کند.

چهار شکل خاص برای اين دستور وجوددارد:

xchg register, memory
xchg register, register
xchg ax, register16

ترتيب علموندها اهمیت ندارد. می توانید xchg mem,reg یا xchg reg,mem را بنویسید نتیجه فرقی ندارد. اکثر اسمبلرها بطور خودکار کد کوتاهتر را انتخاب می کنند.

هردو عملوند باید یک اندازه باشند.

دستور xchg روی هيچيک از فلگ ها تاثیر نمی گذارد.


LEA

دستورالعمل (load effective address) lea برای مقداردهی اشاره گرها استفاده می شود. فرم خاص آن به صورت زیر است:

lea register16, memory

اين دستور آدرس موثر يک محل خاص از حافظه را درون یک ثبات همه منظوره ذخيره می کند. منظور از آدرس موثر آدرس نهائی حافظه بعد از کلیه محاسبات آدرسی است.


مثال. دستور زير مقدار 1234h را در ثبات AX قرار می دهد.

lea AX, DS:[1234h]


دستور mov ax, immediate data هم همین عمل را انجام می دهد. تفاوت آنها در اين است که دستورالعمل lea محاسبه آدرسی و انتقال داده را همزمان انجام می دهد.


مثال. دستور زير آدرس حاصل از محاسبه BP+SI+4 را درثبات AX قرار می دهد. ابتدا مقادير را بهم جمع کرده سپس در ثبات منتقل می کند.

lea bx, 4[bp+si]


دستورالعمل lea روی فلگ ها تاثير ندارد.

برنامه Debug محيطی برای بررسی فايل های مقصد دودوئی و اجرائی است. برنامه امکان انجام تغييرات جزئی در يک برنامه اجرائی را فراهم می کند بدون اينکه نياز به دوباره اسمبل کردن آن باشد.


برنامه Debug ابزاری جهت اشکالزدائی، اجرا و تغيير برنامه ها می باشد. اين برنامه امکان نوشتن و اجرای برنامه های کوتاه اسمبلی، نمايش و تغيير محتوای حافظه و ثبات ها، تهيه ليست اسمبلی از يک برنامه اجرائی و دسترسی به پورت ها را می دهد

برنامه Debug جزو فرامين خارجی سيستم عامل DOS است و همراه با سيستم عامل نصب می شود. در سيستم عامل ويندوز می توانيد آنرا در شاخه WINDOWSsystem32 پيدا کنيد.

به دو طريق می توان Debug را اجرا کرد. در روش اول تنها نام برنامه Debug در خط فرمان سيستم عامل وارد می شود. در روش دوم نام يک فايل اجرائی و ليست پارامترهای موردنياز آن مقابل کلمه Debug وارد می شود. در اين حالت فايل اجرائی در حافظه لود می شود و تعداد بايت های آن در ثبات های BX:CX قرار می گيرد.

محاسبات کامپيوتري در مبناي دو انجام مي شود. به طور معمول از سيستم عددي هگزادسيمال براي نمايش اعداد باينري استفاده مي شود.

سيستم هاي عدد نويسي
سيستم عددی اعشاری
سيستم عددی دودوئی
سيستم عددی هگز

سيستم هاي عدد نويسي

در کارهای روزمره از سيستم عددی اعشاری يا مبنای 10 استفاده می شود. اين سيستم برای کامپيوتر مناسب نيست و برای سادگی سخت افزار، کليه اطلاعات به شکل بيت های روشن و خاموش رمز می شوند. بنابراين سيستم عددی باينری که تنها شامل ارقام صفر و يک است برای اين منظور بسيار مناسب است. عدد 1 (on) مشخص کننده +5 ولت و عدد صفر (off) مشخص کننده 0.5 ولت است.

برای تعيين مبنای عدد يک حرف کوچک در انتهای آن قرار می گيرد. مثاال 45h به معنی عدد 45 در مبنای شانزده است. و 11010011b يعنی اين عدد در مبنای 2 است. اين روشی است که اسمبلر اعداد را در برنامه های اسمبلی تشخيص می دهد.

ادامه مطلب...
به کانال تلگرام سایت ما بپیوندید