PDA

View Full Version : سوال: در مورد جامپ شرطی و دستورات شیفت منطقی



Kboy-9043
پنج شنبه 25 خرداد 1391, 19:52 عصر
سلام دوستان.

1. در مورد اینکه جامپ های شرطی مثل زیر که گفته می شه:
مثلا: jne P
فاصله بین این دستور پرش شرطی تا دستور P باید بین 128- تا 127 باشد.
چطوری به صورت دستی در داخل برنامه ای که این مورد فاصله رو رعایت نکرده رو محاسبه کنیم؟
مثلا چندخط برنامه نوشته شده و حالا همون جامپ شرطی هم نوشته شده، حالا ما برنامه رو اسمبل
می کنیم ولی همین error رعایت نکردن فاصله در محدوده 128- تا 127 رو اسمبلر نشون می ده.
سوال اصلیم اینه که چطوری بدون اینکه با اسمبلر خطا رو بفهمیم، خودمون به صورت دستی بدونیم که این جامپ error خواهد و فاصله اش از محدوده قانونی بیشتر خواهد بود؟چطور هر دستور رو شمارش کنیم تا بفهمیم بیشتر از محدوده فوق خواهد بود؟اگر می شود با مثال بگویید ممنون می شوم.


2.در مورد دستورات شيفت به چپ منطقي و شيفت به راست منطقي سوال دارم:
=====
1. وقتي

mov cl,3
sll n,cl

منظورش ايا اينه که مقدار n رو در 6 ضرب کن (در مبناي دسيمال) ؟
-----------
sll n,1

منظورش ايا اينه که مقدار n رو در 2 ضرب کن (در مبناي دسيمال) ؟
=====
2. وقتي

mov cl,3
srl n,cl

منظورش ايا اينه که مقدار n رو بر 6 تقسيم کن (در مبناي دسيمال) ؟
-----------
srl n,1

منظورش ايا اينه که مقدار n رو بر 2 تقسيم کن (در مبناي دسيمال) ؟
=====

ممنونم.

MostafaMohammadi
پنج شنبه 25 خرداد 1391, 23:28 عصر
سلام دوستان.

1. در مورد اینکه جامپ های شرطی مثل زیر که گفته می شه:
مثلا: jne P
فاصله بین این دستور پرش شرطی تا دستور P باید بین 128- تا 127 باشد.
چطوری به صورت دستی در داخل برنامه ای که این مورد فاصله رو رعایت نکرده رو محاسبه کنیم؟
مثلا چندخط برنامه نوشته شده و حالا همون جامپ شرطی هم نوشته شده، حالا ما برنامه رو اسمبل
می کنیم ولی همین error رعایت نکردن فاصله در محدوده 128- تا 127 رو اسمبلر نشون می ده.
سوال اصلیم اینه که چطوری بدون اینکه با اسمبلر خطا رو بفهمیم، خودمون به صورت دستی بدونیم که این جامپ error خواهد و فاصله اش از محدوده قانونی بیشتر خواهد بود؟چطور هر دستور رو شمارش کنیم تا بفهمیم بیشتر از محدوده فوق خواهد بود؟اگر می شود با مثال بگویید ممنون می شوم.
شماره خطی که می خوای بهش پرش بکنی رو منهای شماره خطی که داری ازش پرش می کنی بکن.
اگه با Notepad برنامه می نویسی و شماره خط رو نمیزنه، برو از ++Notepad استفاده کن.
راه حل خارق العاده خاصی وجود نداره، بعلاوه فکر کنم این محدودیت توی ورژن های جدید برداشته شده، چک کردی؟

Kboy-9043
جمعه 26 خرداد 1391, 07:56 صبح
ممنونم دوست خوبم.

جواب سوال دوم رو اگر می شه بگویید.

ممنونم.

ssbostan
جمعه 26 خرداد 1391, 09:30 صبح
با سلام؛
توجه كنيد كه محدوده پرش به بايت محاسبه ميشه، نه خط...!
براي اينكه خودتون بفهميد بايد بشينيد محاسبه كنيد كه مجموع عملگرهايي كه استفاده كردين چند بايت ميشن و بعد تشخيص بديد كه خارج از محدوده رفتيد يا نه.

در عملگر هاي شيفت هيچگونه ضربي صورت نميگيره.
ما دو نوع عملگر شيفت داريم.
1- منطقي(shl, shr)
2- حسابي(sal, sar)

كه براتون با مثال توضيح ميدم متوجه بشيد.



mov al, 00110010b
shl al, 1


; al before shift: 00110010
; al after shift: 01100100


همينطور كه ميبينيد مقدار al به سمت چپ به اندازه يك خانه حركت كرده و يك صفر هم به سمت راست اضافه شده.
مشخص هست كه اگر اين عدد رو با shr به سمت راست حركت بديد به اينصورت خواهد شد:


mov al, 00110010b
shr al, 1


; al before shift: 00110010
; al after shift: 00011001

ميبينيد كه عدد به اندازه يك خانه به سمت راست حركت كرد و يك صفر به سمت چپ اضافه شد.

عملگرهاي شيفت براي حركت دادن اعداد به سمت چپ و راست هستن.
عملگر هاي شيفت حسابي هم به همين شكل هستن با اين تفاوت كه در عملگر sar اگر بيت علامت يك باشه، يعني عدد منفي باشه، شيفت به صورت بالا كه گفتم انجام ميشه، اما بيت علامت تغيير نميكنه.

مثال:


mov al, 10110010b
sar al, 1


; al before shift: 10110010
; al after shift: 11011001


موفق باشيد.

Kboy-9043
جمعه 26 خرداد 1391, 11:53 صبح
ممنونم ازتون دوست خوبم.

اگر به سوالم توجه کرده باشید گفتم مبنای 10 ؟
منظورم این هستش که ما وقتی می گوییم sll n,1 درسته در مبنای دو عملیات انجام می شه ولی اگر همون مبنای دو رو بعد از عملیات شیفت به دسیمال ببریم می شه ضرب در دو.





mov al, 00110010b ; ==> decimal: 50
shl al,1
;
al before shift: 00110010 ; ==> decimal: 50
al after shift: 01100100 ; ==> decimal: 100 (50x2=100)



منظور تمام سوالاتم به این شکل هستش. ؟

در ضمن در مورد همین خطای جامپ و نحوه محاسبه بایت هر عملگر هم می شه یک مثال کوچک بزنید؟

ممنونم.

ssbostan
شنبه 27 خرداد 1391, 15:53 عصر
با سلام؛

عملگر هاي شيفت كاري به ضرب ندارن. چراكه ضرب بايت در بايت يك كلمه ميشه و عملگر هاي شيفت با شيفت كردن، بايت رو به كلمه تبديل نميكنن.

در مورد پرش هم:



nop ; 1 byte
mul ax ; 2 byte
mul ah ; 2 byte
mov ax, 1 ; 3 byte
mov ah, 1 ; 2 byte
cmp ax, 1 ; 3 byte
cmp ah, 1 ; 3 byte


موفق باشيد.

MostafaMohammadi
دوشنبه 29 خرداد 1391, 02:14 صبح
توجه كنيد كه محدوده پرش به بايت محاسبه ميشه، نه خط...!
ممنون ssbostan عزیز،
من این رو نمیدونستم.

Kboy-9043 عزیز،
شرمنده بابت راهنمای نادرست.