ساختارهای کنترلی نظير عبارات شرطی و حلقه های تکرار توسط دستورات پرش ساخته می شود. 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 |
پرش در صورتی که کوچکتر است | jnge | jnl |
jnge | Sign |
پرش در صورتی که بزرگتر يا مساوی نيست | jl | jge |
jle | Sign |
پرش در صورتی که کوچکتر يا مساوی است | jng | jnle |
jng | Sign |
پرش در صورتی که بزرگتر نيست | 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: