حلقه تکرار و ضرب در اسمبلی

scooter2005

Member
اگر بخوایم برنامه ای بنویسیم که ax=10 باشد و دستور زیر 5 بار تکرار شود شود
ax=ax*2

جوابش میشه :
mov 10,ax
mov 5,cx
l1=
shl 1,ax
loop l1

حالا اگر بخوایم دستور ضرب رو انجام بدیم در این حلقه بدون استفاده از shl این درست هست ؟

mov 10 ,ax
mov cx , 5
l1=
2 , al
mul ax
loop l1
 

the_king

مدیرکل انجمن
اگر بخوایم برنامه ای بنویسیم که ax=10 باشد و دستور زیر 5 بار تکرار شود شود
ax=ax*2

جوابش میشه :
mov 10,ax
mov 5,cx
l1=
shl 1,ax
loop l1

حالا اگر بخوایم دستور ضرب رو انجام بدیم در این حلقه بدون استفاده از shl این درست هست ؟

mov 10 ,ax
mov cx , 5
l1=
2 , al
mul ax
loop l1
نه، اشتباهه، قرار بر این است که مقدار ax که از ترکیب دو رجیستر al و ah ایجاد می شود را در 2 ضرب کنید،
زمانی که شما مقدار al را برابر 2 قرار می دهید، عملا بخشی از مقدار قبلی ax را تخریب می کنید، بنابر این
مقدار ax را پیش از ضرب کردن خراب کرده اید. شما نبایستی برای ضرب کردن از ax هم به عنوان مقدار مضروب
استفاده کنید و هم مضرب.

در ضمن رجیستر al یک بایتی است و برای ضرب کردن مقدار ax (که دو بایتی است) مناسب نیست.
اگر از یک رجیستر یک بایتی مثل al یا bl یا ch و ... استفاده کنید، فقط نصف ax یعنی al را در 2 ضرب می کنید،
نه کل دو بایت ax را. بایستی برای مضرب 2 از یک رجیستر دو بایتی مستقل دیگری مانند bx استفاده کنید :

کد:
mov	ax, 10
mov	cx, 5
mov	bx, 2
l1:
mul	bx
loop	l1

مقدار دهی bx را پیش از حلقه انجام دادم، چون مقدار bx همیشه 2 خواهد بود و در حین اجرای حلقه نیازی
به مقدار دهی مجدد آن نیست.

توجه داشته باشید که یکی از دو عملوند ضرب در دستور mul همیشه accumulator است، یعنی ax یا al

در هنگام قرار دادن کدتان در پست های فروم از دکمه (
code.gif
) استفاده کنید تا کدتان در میان تگ های CODE قرار گیرد.
اینطوری چپ به راست نمایش یافته و خوانایی بهتری خواهد داشت و به هم نمی ریزد.

همچنین برچسب ها را بصورت :l1 مشخص کنید نه =l1
 

scooter2005

Member
ممنون از پاسخ ولي اگر همين چيزي كه شما گفتيد رو اينجوري بنويسيم چي ؟
کد:
mov    ax, 10
mov    cx, 5
mov    dx, 2
l1:
mul    ax
loop    l1

آخه اين جوري كه شما مي گيد 2 رو ريختيم در bx بعد دوباره ضرب در bx كرديم . من اينجاش رو متوجه نشدم
 

the_king

مدیرکل انجمن
ممنون از پاسخ ولي اگر همين چيزي كه شما گفتيد رو اينجوري بنويسيم چي ؟
کد:
mov    ax, 10
mov    cx, 5
mov    dx, 2
l1:
mul    ax
loop    l1

آخه اين جوري كه شما مي گيد 2 رو ريختيم در bx بعد دوباره ضرب در bx كرديم . من اينجاش رو متوجه نشدم

نه، نحوه عملکرد فرمان MUL رو درست متوجه نشدید، با توضیحات بیشتر ابهام تون رو رفع می کنم :

فرمان MUL ای که در پردازنده های 8086 وجود دارد، یا دو عدد 8 بیتی را در هم ضرب می کند، و یا دو عدد 16 بیتی.

ضرب دو عدد 8 بیتی در هم برای بدست آوردن حاصل ضرب 16 بیتی :
اگر به عنوان پارامتر فرمان MUL، یک رجیستر یا خانه حافظه 8 بیتی مشخص کنید، مثلا BL یا CH یا AH،
آنگاه مقدار موجود در رجیستری که مشخص کردید، همیشه در رجیستر AL ضرب شده و نتیجه
در AX قرار می گیرد.

مثلا اگر فرمان MUL CL اجرا شود، مقدار موجود در CL در AL ضرب شده و نتیجه در AX قرار می گیرد.
مثلا اگر فرمان MUL DH اجرا شود، مقدار موجود در DH در AL ضرب شده و نتیجه در AX قرار می گیرد.
مثلا اگر فرمان MUL AL اجرا شود، مقدار موجود در AL در AL ضرب شده و نتیجه در AX قرار می گیرد.

ضرب دو عدد 16 بیتی در هم برای بدست آوردن حاصل ضرب 32 بیتی :
اگر به عنوان پارامتر فرمان MUL، یک رجیستر یا خانه حافظه 16 بیتی مشخص کنید، مثلا BX یا CX یا AX،
آنگاه مقدار موجود در رجیستری که مشخص کردید، همیشه در رجیستر AX ضرب شده و نتیجه
در ترکیب دو رجیستر AX و DX قرار می گیرد. 16 بیت کم ارزش حاصل ضرب در AX و 16 بیت
با ارزش حاصل ضرب در DX قرار می گیرد.

مثلا اگر فرمان MUL CX اجرا شود، مقدار موجود در CX در AX ضرب شده و نتیجه در DX:AX قرار می گیرد.
مثلا اگر فرمان MUL DX اجرا شود، مقدار موجود در DX در AX ضرب شده و نتیجه در DX:AX قرار می گیرد.
مثلا اگر فرمان MUL AX اجرا شود، مقدار موجود در AX در AX ضرب شده و نتیجه در DX:AX قرار می گیرد.

حال ابتدا کدی که شما نوشتید را بررسی کنیم :
ابتدا مقدار 10 را در AX و مقدار 5 را در CX و مقدار 2 را در DX قرار دادید:
کد:
mov    ax, 10
mov    cx, 5
mov    dx, 2

در داخل حلقه مقدار موجود در AX را در AX ضرب کرده (10 ضربدر 10) و حاصل را در DX:AX قرار می دهید
(عدد 100 در AX و عدد 0 در DX قرار می گیرد).
کد:
mul    ax

حلقه 4 بار دیگر بایستی تکرار شود :
کد:
loop    l1

پس در اجرا دوم حلقه، مقدار موجود در AX را در AX ضرب کرده (100 ضربدر 100) و حاصل در DX:AX قرار می گیرد
(عدد 10000 در AX و عدد 0 در DX قرار می گیرد).

در اجرا سوم حلقه، مقدار موجود در AX در AX ضرب شده (10000 در 10000) و حاصل در DX:AX قرار می گیرد
(عدد 57600 در AX و عدد 1525 در DX قرار می گیرد).

همانطور که مشاهده می کنید، عملی که انجام می شود هیچ ارتباط منطقی با ضرب کردن AX در مقدار 2 ندارد.

حال کدی را بررسی کنیم که حقیر نوشتم :
کد:
mov	ax, 10
mov	cx, 5
mov	bx, 2
l1:
mul	bx
loop	l1

ابتدا مقدار 10 را در AX و مقدار 5 را در CX و مقدار 2 را در BX قرار می دهیم :
کد:
mov	ax, 10
mov	cx, 5
mov	bx, 2

در داخل حلقه مقدار BX (که 2 است و در آن تغییری داده نمی شود) را در AX ضرب کرده و حاصل را در DX:AX
قرار می دهیم :
کد:
mul	bx

پس در اولین اجرای کد داخل حلقه، مقدار موجود در BX را در AX ضرب کرده (2 ضربدر 10) و حاصل را در DX:AX قرار می دهیم (عدد 20 در AX و عدد 0 در DX قرار می گیرد).

حلقه 4 بار دیگر بایستی تکرار شود :
کد:
loop    l1

پس در اجرا دوم حلقه، مقدار موجود در BX را در AX ضرب کرده (2 ضربدر 20) و حاصل را در DX:AX قرار می دهیم
(عدد 40 در AX و عدد 0 در DX قرار می گیرد).

در اجرا سوم حلقه، مقدار موجود در BX در AX ضرب شده (2 ضربدر 40) و حاصل در DX:AX قرار می گیرد
(عدد 80 در AX و عدد 0 در DX قرار می گیرد).

و ...
 

جدیدترین ارسال ها

بالا