آموزش اسمبلی بخش 5
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
دستورات
منطقی
دستورات منطقی 8086 عمليات منطقی and، or، xor و not را به صورت بيت به بيت روی عملوندها انجام می دهند. AND OR XOR NOT TEST دستکاری بيت ها AND دستورالعمل and عمل and منطقی را روی دو عملوند خود انجام می دهد و نتيجه را در عملوند اول ذخيره می کند. فرم کلی آن به صورت زير است: and dest, src طبق جدول زير عمل and روی بيت های متناظر دو عملوند انجام می شود. هر بيت نتيجه در صورتی يک است که بيت های متناظر هر دو عملوند يک باشند در غير اينصورت صفر می شود. A B A and B 1 1 1 1 0 0 0 1 0 0 0 0 دستورالعمل and به شکل های زير می تواند بکار برود: and register, register and memory, register and register, memory and register, immediate data and memory, immediate data and /AL, immediate data دستورالعمل and روی فلگ های زير تاثير می گذارد: • فلگ carry و overflow را صفر می کند. • فلگ های zero، sign و parity با توجه به نتيجه تاثير می پذيرند. فلگ zero وقتي دو عملوند در هيچ مکانی بيت مشابه نداشته باشند يک می شود. مثال mov AX, C123h and AX, 82F6h دستورالعمل and برای محاسبه سريع باقيمانده يک عدد بر توانی از 2 می تواند استفاده شود. برای پيدا کردن باقيمانده عملوندی بر مقدار 2n کافيست and عملوند با مقدار 2n-1 محاسبه شود. مثال. دستور زير باقيمانده بر عدد 8 را محاسبه می کند. and AX, 7 OR دستورالعمل or عمل or منطقی را روی عملوندهای خود انجام می دهد. فرم کلی آن به صورت زير است: or dest, src عمل or، طبق جدول زير، روی عملوندها بيت به بيت انجام می گيرد. هر بيت نتيجه دستور or در صورتی صفر است که بيت های متناظر هر دو عملوند صفر باشند در غير اينصورت يک می شود. A B A or B 1 1 1 1 0 1 0 1 1 0 0 0 دستورالعمل or مشابه عمل and روی فلگ های Carry، Zero، Sign، Overflow و Parity تاثير می گذارد. فلگ zero وقتی يک می شود که هردو عملوند صفر باشند. عملوندهای دستورالعمل or مشابه دستورالعمل and می تواند ثبات، حافظه يا داده فوری باشد. مثال. mov AX, C123h or AX, E831h XOR دستورالعمل xor عمل xor منطقی را روی بيت های دو عملوند خود انجام می دهد و نتيجه را در عملوند اول ذخيره می کند. فرم کلی آن به صورت زير است: xor dest, src هر بيت نتيجه دستورالعمل xor مطابق جدول زير تنظيم می شد. بيت نتيجه زمانی صفر است که هردو بيت عملوند مشابه هم باشند درغير اينصورت يک می شود. A B A xor B 1 1 0 1 0 1 0 1 1 0 0 0 دستورالعمل xor مشابه عمل and روی فلگ ها تاثير می گذارد. اگر هردو عملوند دستورالعمل مساوی باشند نتيجه صفر می شود و در نتيجه فلگ zero يک می شود. برای صفر کردن ثبات ها می توان از دستورالعمل xor register, register استفاده کرد که کوتاهتر از دستورالعمل mov register,0 است. مثال. mov AX, C123h xor AX, E831h NOT دستورالعمل not مکمل يک عملوند خود را محاسبه و در آن ذخيره می کند. فرم کلي آن به صورت زير است: not dest دستورالعمل not بيت های عملوند را عکس می کند؛ صفرها را به يک و يک ها را به صفر تبديل می نمايد. دستورالعمل not به يکی از دو حالت زير می تواند استفاده شود: not register not memory دستورالعمل not روی هيچکدام از فلگ ها تاثير ندارد. مثال. mov AX, C123h not TEST دستورالعمل test مشابه and است و عمل and منطقی را روی دو عملوند خود انجام می دهد با اين تفاوت که نتيجه را جائی ذخيره نمی کند. test dest, src فلگ های Carry، Zero، Sign، Overflow و Parity مشابه دستورالعمل and تاثير می پذيرند. دستورالعمل test برای بررسی يک بودن بيتی می تواند استفاده شود. مثال. دستور زير مقدار 1 را با ثبات AL به طور منطقی and می کند. اگر بيت شماره 0 ثبات AL صفر باشد نتيجه دستور صفر شده و فلگ zero برابر با يک می شود در غير اينصورت فلگ zero صفر می شود. بررسی فلگ zero بعد از اين اجرای دستور نشان می دهد که بيت صفر ثبات AL يک بوده است يا خير. test AL, 1 مثال. دستور زيرا برای بررسی بيت های 0، 2 و 8 ثبات DX می تواند استفاده شود. اگر همگی صفر باشند فلگ zero يک می شود. test DX, 105h دستکاری بيت ها از دستورات منطقی برای دستکاری بيت های معينی از عملوند مقصد بدون تاثير روی بيت های ديگر آن می استفاده می شود. برای اين منظور يک ماسک ساخته می شود. يک ماسک مقدار است که بيت های مشخصی از يک عملوند را صفر يا يک می کند بدون اينکه نغييری روی بقيه بيت های آن داشته باشد. صفر کردن بيت ها با دستورالعمل AND با دقت در جدول and می توان مشاهده کرد که نتيجه and عدد صفر با هر بيتی برابر با صفر می شود. اگر عدد يک با بيتی and شود نتيجه همان بيت می شود. از اين خاصيت برای صفر کردن بيت های انتخابی يک مقدار بدون تاثير روی بقيه بيت ها می توان استفاده کرد. مثال. درمثال زير بيت شماره 5 ثبات صفر می شود و بقيه بيت ها بدون تغيير باقی می مانند. mov AX, C123h and AX, FFDFh يک کردن بيت ها با دستورالعمل OR دستورالعمل or را می توانيد برای يک کردن بيت های انتخابی يک عدد بکار ببريد. مثال. درمثال زير بيت شماره 3 ثبات يک می شود و بقيه بيت ها بدون تغيير باقی می مانند. mov AX, C123h or AX, 8 دستورات شيفت دستورات شیفت يک رشته بیتی را به سمت راست يا چپ حرکت می دهند. توسط اين دستورات می توان روی بيت های داده کار کرد؛ داده را ادغام يا جدا کرد و عمليات محاسباتی را انجام داد. ريزپردازنده 8086 سه دستورالعمل شيفت (shl/sal، shr و sar) دارد. بخش زير هر يک از اين دستورالعمل ها را شرح می دهد. SHL/SAL SHR SAR کاربردهای شيفت عمل شيفت بيت های داده را حرکت می دهد. حرکت بيت ها می تواند به سمت چپ (به سمت بيت های با ارزش) يا راست (به سمت بيت های کم ارزش) باشد. فلگ Carry معمولا آخرین بيت شیفت داده شده که از عملوند خارج می شود را می گيرد. دو نوع شيفت وجود دارد: شيفت منطقی و شيفت رياضی. شيفت منطقی ساده ترين شيفت است که به طريق ساده ای بيت ها را شيفت می دهد. در شيفت رياضی علامت عدد حفظ می شود. مثال. يک عدد شيفت داده شده يک بايتی نشان داده شده است. توجه کنيد که بيت های جديدی که وارد می شوند هميشه صفر هستند. 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 دستورات چرخش دستورات چرخش رشته های بيتی را به صورت دايره ای حرکت می دهد اين دستورات مشابه شيفت عمل می کنند با اين تفاوت که بيتی که از يک طرف از داده خارج می شود به طور دوار از جهت ديگر وارد آن می شود. پردازنده 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 و Auxiliarycarry تاثير ندارد. اگر نيازداريد مقدار اين فلگ ها را بعد از عمل چرخش بدانيد نتيجه را با صفر مقايسه کنيد تا اين فلگ ها تنظيم شوند. مثال. 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 چند نوع دستورالعمل پرش را در اختيار می گذارد. دستور پرش بدون شرط دستورات پرش شرطی ساختار شرط دستورات برنامه پشت سر هم اجرا می شوند يعنی پردازنده دستورات را به ترتيبی که در برنامه ظاهر شده اند اجرا می کند. ساختارهای کنترلی نظير عبارات شرطی، حلقه ها و فراخوانی زيربرنامه روال اجرای برنامه را تغيير می دهد. زبان های سطح بالا ساختارهای کنترلی سطح بالا مانند دستورات if و while را دراختيار می گذارند که اجرای برنامه را کنترل می کنند. زبان اسمبلی چنين ساختارهای پيچيده ای را ندارد در عوض از دستورات پرش برای پياده سازی اين ساختارهای کنترلی استفاده می شود(که البته استفاده نامناسب آن باعث کد اسپاگتی می شود). دستورات پرش اجرای برنامه را به نقطه دلخواهی منتقل می کنند. دو نوع دستورالعمل پرش وجود دارد: • دستورات پرش بدون شرط • دستورات پرش شرطی گونه های مختلفی از دستورات پرش وجود دارند: • کوتاه (short). اين نوع پرش بسيار محدود است و تنها می تواند 128 بايت بالا يا پايين بپرد. مزيت آن در مصرف کمتر حافظه است. ميزان جابجائی تنها توسط يک بايت مشخص می شود که تعيين می کند چند بايت جلوتر يا عقب تر برود. اين فاصله به ثبات IP اضافه می شود. • نزديک (near). اين نوع پرش می تواند به هر موقعيت درون يک سگمنت پرش کند. • دور (far). اين نوع پرش اجازه حرکت به سگمنت های ديگر را می دهد. دستور پرش بدون شرط دستورالعمل (jump) jmp بدون هيچ شرطی کنترل را به نقطه ديگری در برنامه منتقل می کند و مشابه دستور goto در زبان های سطح بالا عمل می کند. فرم کلی آن به صورت زير است: jmp target target می تواند آدرسی درون همين سگمنت يا سگمنت کد ديگری باشد. معمولا آدرس مقصد توسط يک برچسب معين می شود. برچسب شناسه ای است که بدنبال آن علامت کلون (:) می آيد. اسمبلر با توجه به آفست دستور بعد از برچسب، فاصله پرش را به طور اتوماتيک محاسبه می کند. دستورالعمل بعد از jmp هيچوقت اجرا نمی شود مگر اين که از دستور ديگری به آن پرش شده باشد. دستور jmp به تنهائی در برنامه موثر نيست و برای ساختن ساختارهای کنترلی همراه با دستورات پرش شرطی استفاده می شود. مثال. حلقه زير مرتب از پورت موازی داده را می خواند و بيت صفر آنرا عکس می کند. اين باعث توليد يک سيگنال مربعی روی يکی از خطوط پورت پرينتر شود. mov DX, 378h ;Parallel printer port address. Forever: in AL, DX ;Read character from input port. xor AL, 1 ;Invert the L.O. bit. out DX, AL ;Output data back to port. jmp Forever ;Repeat forever. دستورات پرش شرطی دستورات پرش شرطی برای ساختن حلقه ها و عبارات شرطی مانند if بکار می روند. پرش های شرطی يک يا چند فلگ را بررسی می کنند و با توجه به وضعيت آنها کنترل را به آدرس معينی منتقل می کنند. اگر پرش انجام نشود اجرا از دستورالعمل بعد از ادامه پيدا می کند. با توجه به اينکه دستورات پرش شرطی فلگ ها را بررسی می کنند قبل از دستور پرش بايد دستوری وجود داشته باشد که روی فلگ ها تاثير بگذارد. برای مثال بعد از اجرای دستور shl می توانيد فلگ Carry را تست کنيد تا ببينيد بيت 1 از سمت چپ عدد خارج شده است يا خير. يا بعد از دستورالعمل test می توانيد فلگ Zero را بررسی کنيد تا ببينيد بيت های مشخصی در يک عدد 1 بوده اند يا خير. البته در اکثر موارد ساختارهای کنترلی بر اساس مقايسه مقادير و توسط cmp پياده سازی می شوند. دستورالعمل cmp با توجه به حاصل تفريق دو عملوند خود فلگ ها را تنظيم می کند بنابراين می تواند برای بررسی بزرگتر، کوچکتر يا مساوی بودن مقادير استفاده شود. برای مقدارهای بدون علامت دو فلگ Carry و Zero از ثبات پرچم مهم هستند و برای اعداد علامتدار فلگ های Sign و Zero اهميت دارند. فلگ Zero در صورتی که مساوی بودن عملوند را نشان می دهد. دستورات پرش تنها فلگ ها را بررسی می کنند و روی آنها تاثيری ندارند. دستورالعمل های پرش شرطی انواع مختلفی دارند که همگی با حرف J شروع می شوند و بعد از آن حروف ديگر قرار می گيرند. بدنبال دستور يک آدرس يا برچسب ذکر می شود. اين دستورات را به سه دسته کلی می توان تقسيم کرد: • دستورات پرش بر اساس فلگ ها • دستورات پرش بعد از مقايسه عملوندهای بدون علامت • دستورات پرش بعد از مقايسه عملوندهای علامتدار توجه داشته باشيد که پرش های شرطی از نوع کوتاه هستند و طول پرش محدود به 128 بايت است برای غلبه براين محدوديت می توانيد ساختار شرط را توسط پرش متضاد بسازيد. در 8086 دستورات مترادفی برای تعدادی از دستورات پرش شرطی وجود دارد. جداول زير مترادف های هر دستور را ليست می کنند. در اين جداول همچنين دستورات متضاد هر دستور شرطی نيز بيان شده است. دستورات پرش بر اساس فلگ ها دستورالعمل شرط شرح مترادف متضاد jc Carry = 1 پرش در صورتی که رقم نقلی وجود دارد jb, jnae jnc jnc Carry = 0 پرش در صورتی که رقم نقلی وجود ندارد jnb, jae jc jz Zero = 1 پرش در صورتی که صفر است je jnz jnz Zero = 0 پرش در صورتی که صفر نيست jne jz js Sign = 1 پرش در صورتی که مثبت است - jns jns Sign = 0 پرش در صورتی که منفی است - js jo Overflow=1 پرش در صورتی که سرريزی وجود دارد - jno jno Overflew=0 پرش در صورتی که سرريزی وجود ندارد - jo jp Parity = 1 پرش در صورتی که پريتی زوج است jpe jnp jnp Parity = 0 پرش در صورتی که پريتی فرد است jpo jp دستورات پرش بعد از مقايسه بدون علامت دستورالعمل شرط شرح مترادف متضاد ja Carry=0, Zero=0 پرش در صورتی که بالاتر است jnbe jna jnbe Carry=0, Zero=0 پرش در صورتی که پايين تر يا مساوی نيست ja jbe jae Carry = 0 پرش در صورتی که بالاتر يا مساوی است jnc, jnb jnae jnb Carry = 0 پرش در صورتی که پايين تر نيست jnc, jae jb jb Carry = 1 پرش در صورتی که پايين تر است jc, jnae jnb jnae Carry = 1 پرش در صورتی که بالاتر يا مساوی نيست jc, jb jae jbe Carry = 1 يا Zero = 1 پرش در صورتی که پايين تر يا مساوی است jna jnbe jna Carry = 1 يا Zero = 1 پرش در صورتی که بالاتر نيست jbe ja je Zero = 1 پرش در صورتی که مساوی است jz jne jne Zero = 0 پرش در صورتی که نامساوی است jnz je دستورات پرش بعد از مقايسه علامتدار دستورالعمل شرط شرح مترادف متضاد jg Sign = Overflow يا Zero=0 پرش در صورتی که بزرگتر است jnle jng jnle Sign = Overflow يا Zero=0 پرش در صورتی که کوچکتر يا مساوی نيست jg jle jge Sign = Overflow پرش در صورتی که بزرگتر يا مساوی است jnl jge jnl Sign = Overflow پرش در صورتی که کوچکتر نيست jge jl jl Sign Overflow پرش در صورتی که کوچکتر است jnge jnl jnge Sign Overflow پرش در صورتی که بزرگتر يا مساوی نيست jl jge jle Sign Overflow يا Zero=1 پرش در صورتی که کوچکتر يا مساوی است jng jnle jng Sign Overflow يا Zero=1 پرش در صورتی که بزرگتر نيست jle jg je Zero = 1 پرش در صورتی که مساوی است jz jne jne Zero = 0 پرش در صورتی که نامساوی است jnz je ساختار شرط از دستورات پرش شرطی می توان برای ساختن عبارات if استفاده کرد. به مثال های زير دقت کنيد. مثال. در دستورات زير اگر Sum>0 باشد به AH مقدار يک را اختصاص می دهد درغير اينصورت BH را يک می کند. cmp Sum, 0 jg Then jmp Else Then: mov AH,1 jmp EndIf Else: mov BH,1 EndIf: مثال. در دستورات زير اگر Total>=100 and Count =0 باشد مقدار Value را با AX جمع می کند. cmp total, 100 jge C2 jmp EndIf C2: cmp Count, 10 je Then jmp EndIf Then: add AX, Value EndIf:
دستورات منطقی 8086 عمليات منطقی and، or، xor و not را به صورت بيت به بيت روی عملوندها انجام می دهند. AND OR XOR NOT TEST دستکاری بيت ها AND دستورالعمل and عمل and منطقی را روی دو عملوند خود انجام می دهد و نتيجه را در عملوند اول ذخيره می کند. فرم کلی آن به صورت زير است: and dest, src طبق جدول زير عمل and روی بيت های متناظر دو عملوند انجام می شود. هر بيت نتيجه در صورتی يک است که بيت های متناظر هر دو عملوند يک باشند در غير اينصورت صفر می شود. A B A and B 1 1 1 1 0 0 0 1 0 0 0 0 دستورالعمل and به شکل های زير می تواند بکار برود: and register, register and memory, register and register, memory and register, immediate data and memory, immediate data and /AL, immediate data دستورالعمل and روی فلگ های زير تاثير می گذارد: • فلگ carry و overflow را صفر می کند. • فلگ های zero، sign و parity با توجه به نتيجه تاثير می پذيرند. فلگ zero وقتي دو عملوند در هيچ مکانی بيت مشابه نداشته باشند يک می شود. مثال mov AX, C123h and AX, 82F6h دستورالعمل and برای محاسبه سريع باقيمانده يک عدد بر توانی از 2 می تواند استفاده شود. برای پيدا کردن باقيمانده عملوندی بر مقدار 2n کافيست and عملوند با مقدار 2n-1 محاسبه شود. مثال. دستور زير باقيمانده بر عدد 8 را محاسبه می کند. and AX, 7 OR دستورالعمل or عمل or منطقی را روی عملوندهای خود انجام می دهد. فرم کلی آن به صورت زير است: or dest, src عمل or، طبق جدول زير، روی عملوندها بيت به بيت انجام می گيرد. هر بيت نتيجه دستور or در صورتی صفر است که بيت های متناظر هر دو عملوند صفر باشند در غير اينصورت يک می شود. A B A or B 1 1 1 1 0 1 0 1 1 0 0 0 دستورالعمل or مشابه عمل and روی فلگ های Carry، Zero، Sign، Overflow و Parity تاثير می گذارد. فلگ zero وقتی يک می شود که هردو عملوند صفر باشند. عملوندهای دستورالعمل or مشابه دستورالعمل and می تواند ثبات، حافظه يا داده فوری باشد. مثال. mov AX, C123h or AX, E831h XOR دستورالعمل xor عمل xor منطقی را روی بيت های دو عملوند خود انجام می دهد و نتيجه را در عملوند اول ذخيره می کند. فرم کلی آن به صورت زير است: xor dest, src هر بيت نتيجه دستورالعمل xor مطابق جدول زير تنظيم می شد. بيت نتيجه زمانی صفر است که هردو بيت عملوند مشابه هم باشند درغير اينصورت يک می شود. A B A xor B 1 1 0 1 0 1 0 1 1 0 0 0 دستورالعمل xor مشابه عمل and روی فلگ ها تاثير می گذارد. اگر هردو عملوند دستورالعمل مساوی باشند نتيجه صفر می شود و در نتيجه فلگ zero يک می شود. برای صفر کردن ثبات ها می توان از دستورالعمل xor register, register استفاده کرد که کوتاهتر از دستورالعمل mov register,0 است. مثال. mov AX, C123h xor AX, E831h NOT دستورالعمل not مکمل يک عملوند خود را محاسبه و در آن ذخيره می کند. فرم کلي آن به صورت زير است: not dest دستورالعمل not بيت های عملوند را عکس می کند؛ صفرها را به يک و يک ها را به صفر تبديل می نمايد. دستورالعمل not به يکی از دو حالت زير می تواند استفاده شود: not register not memory دستورالعمل not روی هيچکدام از فلگ ها تاثير ندارد. مثال. mov AX, C123h not TEST دستورالعمل test مشابه and است و عمل and منطقی را روی دو عملوند خود انجام می دهد با اين تفاوت که نتيجه را جائی ذخيره نمی کند. test dest, src فلگ های Carry، Zero، Sign، Overflow و Parity مشابه دستورالعمل and تاثير می پذيرند. دستورالعمل test برای بررسی يک بودن بيتی می تواند استفاده شود. مثال. دستور زير مقدار 1 را با ثبات AL به طور منطقی and می کند. اگر بيت شماره 0 ثبات AL صفر باشد نتيجه دستور صفر شده و فلگ zero برابر با يک می شود در غير اينصورت فلگ zero صفر می شود. بررسی فلگ zero بعد از اين اجرای دستور نشان می دهد که بيت صفر ثبات AL يک بوده است يا خير. test AL, 1 مثال. دستور زيرا برای بررسی بيت های 0، 2 و 8 ثبات DX می تواند استفاده شود. اگر همگی صفر باشند فلگ zero يک می شود. test DX, 105h دستکاری بيت ها از دستورات منطقی برای دستکاری بيت های معينی از عملوند مقصد بدون تاثير روی بيت های ديگر آن می استفاده می شود. برای اين منظور يک ماسک ساخته می شود. يک ماسک مقدار است که بيت های مشخصی از يک عملوند را صفر يا يک می کند بدون اينکه نغييری روی بقيه بيت های آن داشته باشد. صفر کردن بيت ها با دستورالعمل AND با دقت در جدول and می توان مشاهده کرد که نتيجه and عدد صفر با هر بيتی برابر با صفر می شود. اگر عدد يک با بيتی and شود نتيجه همان بيت می شود. از اين خاصيت برای صفر کردن بيت های انتخابی يک مقدار بدون تاثير روی بقيه بيت ها می توان استفاده کرد. مثال. درمثال زير بيت شماره 5 ثبات صفر می شود و بقيه بيت ها بدون تغيير باقی می مانند. mov AX, C123h and AX, FFDFh يک کردن بيت ها با دستورالعمل OR دستورالعمل or را می توانيد برای يک کردن بيت های انتخابی يک عدد بکار ببريد. مثال. درمثال زير بيت شماره 3 ثبات يک می شود و بقيه بيت ها بدون تغيير باقی می مانند. mov AX, C123h or AX, 8 دستورات شيفت دستورات شیفت يک رشته بیتی را به سمت راست يا چپ حرکت می دهند. توسط اين دستورات می توان روی بيت های داده کار کرد؛ داده را ادغام يا جدا کرد و عمليات محاسباتی را انجام داد. ريزپردازنده 8086 سه دستورالعمل شيفت (shl/sal، shr و sar) دارد. بخش زير هر يک از اين دستورالعمل ها را شرح می دهد. SHL/SAL SHR SAR کاربردهای شيفت عمل شيفت بيت های داده را حرکت می دهد. حرکت بيت ها می تواند به سمت چپ (به سمت بيت های با ارزش) يا راست (به سمت بيت های کم ارزش) باشد. فلگ Carry معمولا آخرین بيت شیفت داده شده که از عملوند خارج می شود را می گيرد. دو نوع شيفت وجود دارد: شيفت منطقی و شيفت رياضی. شيفت منطقی ساده ترين شيفت است که به طريق ساده ای بيت ها را شيفت می دهد. در شيفت رياضی علامت عدد حفظ می شود. مثال. يک عدد شيفت داده شده يک بايتی نشان داده شده است. توجه کنيد که بيت های جديدی که وارد می شوند هميشه صفر هستند. 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 دستورات چرخش دستورات چرخش رشته های بيتی را به صورت دايره ای حرکت می دهد اين دستورات مشابه شيفت عمل می کنند با اين تفاوت که بيتی که از يک طرف از داده خارج می شود به طور دوار از جهت ديگر وارد آن می شود. پردازنده 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 و Auxiliarycarry تاثير ندارد. اگر نيازداريد مقدار اين فلگ ها را بعد از عمل چرخش بدانيد نتيجه را با صفر مقايسه کنيد تا اين فلگ ها تنظيم شوند. مثال. 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 چند نوع دستورالعمل پرش را در اختيار می گذارد. دستور پرش بدون شرط دستورات پرش شرطی ساختار شرط دستورات برنامه پشت سر هم اجرا می شوند يعنی پردازنده دستورات را به ترتيبی که در برنامه ظاهر شده اند اجرا می کند. ساختارهای کنترلی نظير عبارات شرطی، حلقه ها و فراخوانی زيربرنامه روال اجرای برنامه را تغيير می دهد. زبان های سطح بالا ساختارهای کنترلی سطح بالا مانند دستورات if و while را دراختيار می گذارند که اجرای برنامه را کنترل می کنند. زبان اسمبلی چنين ساختارهای پيچيده ای را ندارد در عوض از دستورات پرش برای پياده سازی اين ساختارهای کنترلی استفاده می شود(که البته استفاده نامناسب آن باعث کد اسپاگتی می شود). دستورات پرش اجرای برنامه را به نقطه دلخواهی منتقل می کنند. دو نوع دستورالعمل پرش وجود دارد: • دستورات پرش بدون شرط • دستورات پرش شرطی گونه های مختلفی از دستورات پرش وجود دارند: • کوتاه (short). اين نوع پرش بسيار محدود است و تنها می تواند 128 بايت بالا يا پايين بپرد. مزيت آن در مصرف کمتر حافظه است. ميزان جابجائی تنها توسط يک بايت مشخص می شود که تعيين می کند چند بايت جلوتر يا عقب تر برود. اين فاصله به ثبات IP اضافه می شود. • نزديک (near). اين نوع پرش می تواند به هر موقعيت درون يک سگمنت پرش کند. • دور (far). اين نوع پرش اجازه حرکت به سگمنت های ديگر را می دهد. دستور پرش بدون شرط دستورالعمل (jump) jmp بدون هيچ شرطی کنترل را به نقطه ديگری در برنامه منتقل می کند و مشابه دستور goto در زبان های سطح بالا عمل می کند. فرم کلی آن به صورت زير است: jmp target target می تواند آدرسی درون همين سگمنت يا سگمنت کد ديگری باشد. معمولا آدرس مقصد توسط يک برچسب معين می شود. برچسب شناسه ای است که بدنبال آن علامت کلون (:) می آيد. اسمبلر با توجه به آفست دستور بعد از برچسب، فاصله پرش را به طور اتوماتيک محاسبه می کند. دستورالعمل بعد از jmp هيچوقت اجرا نمی شود مگر اين که از دستور ديگری به آن پرش شده باشد. دستور jmp به تنهائی در برنامه موثر نيست و برای ساختن ساختارهای کنترلی همراه با دستورات پرش شرطی استفاده می شود. مثال. حلقه زير مرتب از پورت موازی داده را می خواند و بيت صفر آنرا عکس می کند. اين باعث توليد يک سيگنال مربعی روی يکی از خطوط پورت پرينتر شود. mov DX, 378h ;Parallel printer port address. Forever: in AL, DX ;Read character from input port. xor AL, 1 ;Invert the L.O. bit. out DX, AL ;Output data back to port. jmp Forever ;Repeat forever. دستورات پرش شرطی دستورات پرش شرطی برای ساختن حلقه ها و عبارات شرطی مانند if بکار می روند. پرش های شرطی يک يا چند فلگ را بررسی می کنند و با توجه به وضعيت آنها کنترل را به آدرس معينی منتقل می کنند. اگر پرش انجام نشود اجرا از دستورالعمل بعد از ادامه پيدا می کند. با توجه به اينکه دستورات پرش شرطی فلگ ها را بررسی می کنند قبل از دستور پرش بايد دستوری وجود داشته باشد که روی فلگ ها تاثير بگذارد. برای مثال بعد از اجرای دستور shl می توانيد فلگ Carry را تست کنيد تا ببينيد بيت 1 از سمت چپ عدد خارج شده است يا خير. يا بعد از دستورالعمل test می توانيد فلگ Zero را بررسی کنيد تا ببينيد بيت های مشخصی در يک عدد 1 بوده اند يا خير. البته در اکثر موارد ساختارهای کنترلی بر اساس مقايسه مقادير و توسط cmp پياده سازی می شوند. دستورالعمل cmp با توجه به حاصل تفريق دو عملوند خود فلگ ها را تنظيم می کند بنابراين می تواند برای بررسی بزرگتر، کوچکتر يا مساوی بودن مقادير استفاده شود. برای مقدارهای بدون علامت دو فلگ Carry و Zero از ثبات پرچم مهم هستند و برای اعداد علامتدار فلگ های Sign و Zero اهميت دارند. فلگ Zero در صورتی که مساوی بودن عملوند را نشان می دهد. دستورات پرش تنها فلگ ها را بررسی می کنند و روی آنها تاثيری ندارند. دستورالعمل های پرش شرطی انواع مختلفی دارند که همگی با حرف J شروع می شوند و بعد از آن حروف ديگر قرار می گيرند. بدنبال دستور يک آدرس يا برچسب ذکر می شود. اين دستورات را به سه دسته کلی می توان تقسيم کرد: • دستورات پرش بر اساس فلگ ها • دستورات پرش بعد از مقايسه عملوندهای بدون علامت • دستورات پرش بعد از مقايسه عملوندهای علامتدار توجه داشته باشيد که پرش های شرطی از نوع کوتاه هستند و طول پرش محدود به 128 بايت است برای غلبه براين محدوديت می توانيد ساختار شرط را توسط پرش متضاد بسازيد. در 8086 دستورات مترادفی برای تعدادی از دستورات پرش شرطی وجود دارد. جداول زير مترادف های هر دستور را ليست می کنند. در اين جداول همچنين دستورات متضاد هر دستور شرطی نيز بيان شده است. دستورات پرش بر اساس فلگ ها دستورالعمل شرط شرح مترادف متضاد jc Carry = 1 پرش در صورتی که رقم نقلی وجود دارد jb, jnae jnc jnc Carry = 0 پرش در صورتی که رقم نقلی وجود ندارد jnb, jae jc jz Zero = 1 پرش در صورتی که صفر است je jnz jnz Zero = 0 پرش در صورتی که صفر نيست jne jz js Sign = 1 پرش در صورتی که مثبت است - jns jns Sign = 0 پرش در صورتی که منفی است - js jo Overflow=1 پرش در صورتی که سرريزی وجود دارد - jno jno Overflew=0 پرش در صورتی که سرريزی وجود ندارد - jo jp Parity = 1 پرش در صورتی که پريتی زوج است jpe jnp jnp Parity = 0 پرش در صورتی که پريتی فرد است jpo jp دستورات پرش بعد از مقايسه بدون علامت دستورالعمل شرط شرح مترادف متضاد ja Carry=0, Zero=0 پرش در صورتی که بالاتر است jnbe jna jnbe Carry=0, Zero=0 پرش در صورتی که پايين تر يا مساوی نيست ja jbe jae Carry = 0 پرش در صورتی که بالاتر يا مساوی است jnc, jnb jnae jnb Carry = 0 پرش در صورتی که پايين تر نيست jnc, jae jb jb Carry = 1 پرش در صورتی که پايين تر است jc, jnae jnb jnae Carry = 1 پرش در صورتی که بالاتر يا مساوی نيست jc, jb jae jbe Carry = 1 يا Zero = 1 پرش در صورتی که پايين تر يا مساوی است jna jnbe jna Carry = 1 يا Zero = 1 پرش در صورتی که بالاتر نيست jbe ja je Zero = 1 پرش در صورتی که مساوی است jz jne jne Zero = 0 پرش در صورتی که نامساوی است jnz je دستورات پرش بعد از مقايسه علامتدار دستورالعمل شرط شرح مترادف متضاد jg Sign = Overflow يا Zero=0 پرش در صورتی که بزرگتر است jnle jng jnle Sign = Overflow يا Zero=0 پرش در صورتی که کوچکتر يا مساوی نيست jg jle jge Sign = Overflow پرش در صورتی که بزرگتر يا مساوی است jnl jge jnl Sign = Overflow پرش در صورتی که کوچکتر نيست jge jl jl Sign Overflow پرش در صورتی که کوچکتر است jnge jnl jnge Sign Overflow پرش در صورتی که بزرگتر يا مساوی نيست jl jge jle Sign Overflow يا Zero=1 پرش در صورتی که کوچکتر يا مساوی است jng jnle jng Sign Overflow يا Zero=1 پرش در صورتی که بزرگتر نيست jle jg je Zero = 1 پرش در صورتی که مساوی است jz jne jne Zero = 0 پرش در صورتی که نامساوی است jnz je ساختار شرط از دستورات پرش شرطی می توان برای ساختن عبارات if استفاده کرد. به مثال های زير دقت کنيد. مثال. در دستورات زير اگر Sum>0 باشد به AH مقدار يک را اختصاص می دهد درغير اينصورت BH را يک می کند. cmp Sum, 0 jg Then jmp Else Then: mov AH,1 jmp EndIf Else: mov BH,1 EndIf: مثال. در دستورات زير اگر Total>=100 and Count =0 باشد مقدار Value را با AX جمع می کند. cmp total, 100 jge C2 jmp EndIf C2: cmp Count, 10 je Then jmp EndIf Then: add AX, Value EndIf:
+ نوشته شده در ۱۳۹۱/۱۰/۱۱ ساعت 14:8 توسط مجید
|