تبلیغات
بچه های برق دانشگاه آزاد کازرون - زبان برنامه نویسی اسمبلی
قالب وبلاگ قالب وبلاگ

بچه های برق دانشگاه آزاد کازرون
 

آپلود عکس رایگان و دائمی
 

اشتراک و ارسال مطلب به:

نوشته شده در تاریخ پنجشنبه 30 تیر 1390 توسط زینب تقی زاده

زبان برنامه نویسی اسمبلی

در ابتدا این سوال مطرح میشود اسمبلی چیست ؟

زبانهای برنامه نویسی كامپیوتر عموما به دو دسته زبانهای سطح بالا و زبانهای سطح پایین تقسیم میشوند . برخی این زبانها را به سه دسته تقسیم بندی كرده اند . زبانهای سطح بالا و زبانهای سطح پایین و زبانهای سطح میانی . زبان برنامه نویسی اسمبلی جز زبانهای سطح پایین است .

زبان سطح پایین به زبانی گفته میشود كه از لحاض ساختاری و ترجمه بسیار به زبان ماشین نزدیك است . یعنی قابلیت فهم ان برای ماشین بهتر و راحتتر است . اما زبانهای سطح بالا با كاربر رابطه بهتری دارند و كاربر یا برنامه نویس با این زبان راحتتر ارتباط برقرار میكند .



در زبان اسمبلی به سبب پایین بودن سطح ان ویژگیهایی نهفته است كه در هیچ یك از زبانهای دیگر این ویژگیها را نمیتوان یافت : یكی از ویژگیهای مهم این زبان باز گذاشتن دست كاربر در كنترل سخت افزار بویژه CPU است . در واقع كاربر میتواند با جز به جز پردازشگر و سخت افزار كامپیوتر ارتباط برقرار كند . بنابراین سرعت اینگونه برنامه ها نسبت به زبانهای سطح بالا بسیار بالاتر است .

البته این زبان دارای مشكلاتی نیز هست . كه از جمله مهمترین انها زیاد بودن تعداد دستوراتی است كه كاربر باید برای انجام عملی خاص از انها استفاده كند .

برنامه نویس برای برنامه نویسی باید بر ارشیتكت ساخت CPU ‌مسلط باشد .

سورس این برنامه ها اصولا خطوط زیادی دارد .

این برنامه ها بسته به ماشین عمل میكنند . یعنی اگر ساختار اصلی ماشین تغییر كند . این برنامه ها قابلیت اجرا ندارند .

اسمبلر چیست ؟

برای تبدیل زبان اسمبلی به زبان ماشین باید از این مترجم استفاده كرد . در واقع زبان اسمبلی از طریق اسمبلر به زبان ماشین كه صفر و یك است ترجمه میشود .

هر خط از زبان اسمبلی معادل یك خط است در زبان ماشین . این ویژگی خاص دستورات اسمبلی است و در زبانها سطح بالا چنین اتفاقی نمی افتد .

نحوه اسمبل شدن برنامه را در شكل زیر میبینید :

 

برای اسمبل كردن یك برنامه توسط اسمبلی باید به یك اسمبلر دسترسی داشت . كه این كار را میتوان توسط یك نرم افزار ویژه انجام داد كه عموما از اسمبلرهای TASM ‌یا MASM استفاده میكنند . كه اولی محصول شركت turbo و دومی محصول مایكروسافت است . كه نسخه جدید MASM نرم افزاری است به نام ML ‌كه كار كردن با ان نسبت به دو نرم افزار بالایی بسیار ساده تر است .

با استفاده از TASM ‌یا MASM سورس برنامه ای كه در فایلی با پسوند asm نوشته اید را به یك فایل obj تبدیل میكنید . سپس با یك لینكر TLINK میتوانید فایل را به فایل اجرایی تسوط كامپیوتر تبدیل كنید كه پسوند exe دارد .

برای نوشتن سورس برنامه كافیست یك ویرایشگر متن داشته باشید كه تمامی كامپیوتر ها چنین چیزی را اصولا دارند . اگر از سیتسم عامل ویندوز استفاده میكنید میتوانید از notepad استفاده كنید اگر از word استفاده میكنید یادتان باشد كه تغییرات اتوماتیك انرا برای تصحیح كلمات از كار بیاندازید . پس از انكه سورس برنامه را نوشتید كافیست انرا با پسوند asm ذخیره كنید برای اینكار از منوی file میتوانید گزینه save as ‌را انتخاب كنید و نام فایل را با پسوند asm در دو جفت كوتیشن قرار میدهید :

“parsx.asm” سپس به پرامپت داس میروید .

برای رفتن به محیط داس اگر از سیستم عامل win98 ‌و نسخه های 9X استفاده میكنید كافیست در منوی استارت گزینه run را انتخاب كنید و سپس بنویسید command و اگر از ویندوزهای با نسخه بالاتر استفاده میكنید میتوانید در منوی run بنویسید cmd و ازانجا به محیط داس بروید و به ادرسی كه اسمبلر شما و فایل asm شما قرار دارد بروید . برای رفتن به این مسیر ها باید كمی بر داس مسلط باشید .

اما برای تغییر دایركتوری بدانید كه میزنید cd namefolder و برای بیرون رفتن از ان میزنید cd\ و برای تغییر درایو نام درایو را بهمراه دو نقطه مینویسید : c: به همین سادگی .

اگر از نرم افزار MASM استفاده میكنید . كافیست تایپ كنید MASM ‌و سپس نام فایل سورس را بنویسید و ترتیب را ادامه دهید تا فایل obj ‌شما ساخته شود . سپس LINK ‌را مینویسید و نام فایلی كه ساخته اید و پسوند obj ‌بان اختصاص داده شده است را مینویسید . مراتب را ادام میدهید .

اگر از ml استفاده میكنید . كافیست نام فایل asm ‌را جلوی ml بنویسید . یعنی مینویسید ml parsx.asm و سپس برنامه شما به exe تبدیل میشود .

برای استفاده از turbo assembler هم كافیست نام فایل را جلوی tasm بنویسید تا obj شما ساخته شود و سپس با tlink نام فایل با پسوند obj فایل exe رابسازید .


tasm parsx.asm

tlink parsx.obj


و بدین ترتیب فایل شما ساخته میشود .

البته روش دیگری برای ساخت فایلهای اسمبلی نیز وجود دارد . كه دارای محدودیتهای زیادی است . كافیست در اعلان داس در هر مسیری كه هستید تایپ كنید debug تا وارد محیط debug ‌شوید .

برای ورود دستورات اسمبلی كلید a ‌را میزنید و enter میزنید و برای خروج از محیط دستورات كافیست بدون نوشتن چیزی دكمه اینتر را بزنید . برای خروج از محیط دیباگ نیز كافیست دكمه q را بزنید و اینتر را بعد از ان بزنید . و برای اجرای دستورات g را بزنید . كه كار كردن با این محیط اموزش ویژه ای را میطلبد


مبناها


ز اونجایی كه زبان ماشین 0و1 هست هر عددی كه به ما میدن باید به این دوعدد تبدیل بشه.

مبنای اعداد:2-8-10-16

كه معمولاً اعداد رو در مبنای 10 به كار میبریم.مثل 12؛45,67895

حالا میخوایم یك عدد مبنای 10 رو به مبنای 2 تبدیل كنیم

1-تقسیمهای متوالی كه همتون بلدین دیگه؟؟؟


35=(100011) ‌‌‌‹در مبنای دو›


2-این راه خیلی آسونتره و اگه یك عدد بزرگ دادن خیلی زودتر میشه به جواب رسید(عدد مورد نظر را به توانهای 2 عدد تجزیه میكنیم تا عدد مورد نظر یا استفاده از توانهای 2 ساخته شود.به جای عددهایی كه داریم 1 میگذاریم)

35=32(5^2)+3

0^2 1^2 2^2 3^2 4^2 5^2

1 1 0 0 0 1 = 35

حالا این سوال پیش میاد كه اعداد منفی رو چه جوری باید به مبنای 2 برد؟؟؟

ابتدا توضیح مختصری درباره ی Bit وByte بدم.

 

به هر كدام از این مربع ها یك بیت گفته میشود با 0 و 1 پر میشود.پس 8^2=256 حالت برای پر شدن این مربع ها وجود دارد.

8bit=1byte 16bit=1Word

32bit=1Dw 64bit=Qw


پس باتوجه به این جدول بازه بایت(برای اعداد مثبت)‍[0,255]=

برای اعداد منفی این مقادیر قرینه نمیشود بلكه با استفاده از قانون مكمل2 اعداد رو منفی میكنیم.

 

نكته:با عوض كردن بیت علامت عدد منفی نمیشود

Byte= [-128,127]

مكمل1 = جای 1و0 عوض میشود (0به جای1 و برعكس)

مكمل2 = از سمت راست به اولین یك رسیدیم بدون تغییر مینویسیم ولی بقیه 0و1 ها عوض میشود.

برای اینكه بیشتر متوجه بشید یك مثال میزنم

عدد 10- را به مبنای 2 ببرید؟

حل:ابتدا عدد 10 را به مبنای دو میبریم (00001010)= 10

توجه كنید كه این مسئله در 8بیت حل میشود و باید صفرهای پشت عدد حتماً نوشته شود

طبق قانون مكمل2 از سمت راست عددها را میخونیم.0 و1 (به یك رسید اعداد عوض میشود)1و0و1و1و1و1.

(11110110)=10- در مبنای دو

با یك سوال این مبحث رو تموم میكنم

10000000 در مبنای دو برابر چه عدد یا عددهایی است؟


عدد 10000000=128- یا 128+ است.این عدد تنها عددی است كه اگر بیت علامت عوض شود عدد قرینه میشود.

ادامه درس:

در ادامه مبحث مبناها به بررسی مبنای 8 و 16 میپردازیم.

مبنای 8:

اعداد 0و1و...و7 را قبول میكند.

111=2^8*1+1^8*5+0^8*7=157(در مبنای 8)


تبدیل مبنای 10 یه 8:

روش تقسیمهای متوالی

 

مبنای 16:

اعداد 0و1و2و...و9وF=15,14=E,13=D,12=C,11=B,10=A

3A(در مبنای 16)=1^16*3+0^16*10=58


تبدیل مبنای 10 به 16:

استفاده از تقسیمهای متوالی.فكر نكنم دیگه لازم باشه توضیح بدم.


برای اینكه مبنای اعداد را نشان بدهند؛راه دیگری هم وجود داره.یعنی به جای اینكه مبنا رو در زیر پرانتز در كنیر اعداد بنویسند.میتوانیم از حروف استفاده كنیم:

B: مبنای2

O: مبنای 8

D: مبنای 10

H: مبنای 16


تا اینجا هر تبدیلی كه خونده بودیم برای مبنای 10 بود حالا تبدیل اعداد به مبنای 2 رو میگم كه كاربرد بیشتری داره

تبدیل از مبنای 8 به 2 و برعكس:

برای تبدیل اعداد از مبنای 8 به مبنای 2 در هررقم مبنای8 معادل سه رقم در مبنای2 میشود.

52O=5(101),2(010( پس 52O=101010

از مبنای 2 به 8:

از سمت راست رقمها را سه تا سه تا جدا میكنیم.هر سه رقم درمبنای2 معادل یك رقم در مبنای8 است.

011 011 101=

335

تبدیل از مبنای 16 به2 و برعكس:

مانند مبنای8 است فقط ارقام به چهار دسته تقسیم میشود.


سوال:2003H-5 معادل چه عددی است؟


یكی دیگر از مبحث هایی كه در زبان اسمبلی شما خیلی استفاده میكنید جمع و تفریق مبناها است.


جمع:

مثل جمع كردن معمولی هست وزیاد فرق نمیكنه.

0+0=0 1+0=1 1+1=10 0+1=1

مثال:

230+110111B=?H

حل:23 در مبنای 8=010011

010011+110111=1001010=4AH


تفریق:

0-1=1 0-0=0 1-1=0 1-0=2(تو تفریق معمولی وقتی یه عدد كوچكتر رو میخواستیم از یه عدد بزرگتر كم كنیم از عدد بعدیش غرض میگرفتیم.در اینجا هم به همین صورت عمل میكنیم.با این تفاوت كه مبنای عدد باید توجه كنیم.مثلاً اگر در مبنای 2 باشه در موقع غرض گرفتن 2واحد به عدد اضاقه میكنیم واگر مبنای 16 باشد 16 واحد)

مثال

202H-76DH=?

حل:

202H=1000000010 , 76D=000011110


از آنجاییكه برنامه نویسی به زبان اسمبلی‌‌‌؛به ماشین ربط دارد؛آشنایی با سخت افزار كامپیوتر هم میتواند در بهتر نوشتن برنامه ها به شما كمك كند.البته من قصد ندارم به طور كامل درباره سخت افزار بحث كنم. در تمام كامپیوترها قسمتی به نام حافظه اصلی یاCPU وجود دارد كه این مجموعه میتواند دستورها یا دادها را به صورت یك بایت ذخیره كند.هر بایت حافظه اصلی دارای یك برچسب عددی با نام آدرس میباشد كه این آدرس هی میتواند از 0000 شروع شده و مقدار ماكزیمم آن برابر عدد بدون علامتFFFF16 باشد.یك آدرس را میتوان با پنج رقم شانزده شانزدهی نشان داد.اندازه ماكزیمم حافظه اصلی برابر 1مگابایت میباشد.

 

اطلاعات در داخلCPU در محلهایی به نام ثبات(Register) ذخیره میشود.رجیستر ها به سه دسته تقسیم میشوند.

1-General Register:(ثبات عمومی)این ها ثبات هایی هستند كه در دستورعمل ها استفاده میشود.به بیان ساده تر بیشتر یا این علامتها سروكار داریم.

Ax: نتایج محاسبات در آن قرار میگیرد به همین دلیل به آن انباره هم گفته میشود

Bx: پایه؛كاربرد همگانی

Cx: شمارش؛كاربرد همگانی

Dx :داده؛كاربرد همگانی

در مورد این نشانه ها در قسمت برنامه نویسی مفصل تر توضیح میدم فقط در این حد كه به گوشتون خورده باشه بدونید

این رجیسترهای همگانی به دو ثبات8بیتی مستقل یعنی نصف بالایی برای 8بیت سمت چپ و نصف پایینی برای8بیت سمت راست استفاده نمود.اسامی این ثباتهای 8بیتی عبارتنداز

AH,AL,BH,BL,CH,CL,DH,DL

 


2-Pointer & index Register: (ثباتهای اشاره گر شاخص)

IP: Instruction pointer اشاره گر دستور العمل؛به دستور العمل درحال اجرا اشاره میكند وبا اجرای دستورات به صورت اتوماتیك عوض میشود

BP: اشاره گر پایه؛معمولاً برای آدرس دهی استفاده میشود

SP: اشاره گر پشته؛به آخرین خانه پرشده پشته(Stock) اشاره میكند.یعنی وقتی اطلاعات در داخل آن قرار میگیرد آخرین اطلاعات اول خارج میشود

SI: شاخص مبدا

DI: شاخص مقصد

SI, DI در آدرس دهی برای گذاشتن یا برداشتن اطلاعات در حافظه اصلی استفاده میشود

3-Segment register(ثباتهای سگمنت)

DS:داده

CS:كد یا برنامه(دستورات به كد تبدیل میشود)

SSپشته(در فراخواندن استفاده میشود)

EX :اضافی(شبیه داده است؛اگر داده زیاد باشد استفاده میشود)


درباره رجیسترها چند مطلب دیگه هم مانده كه در اینجا میگم.

از پردازنده های 386 به بعد(+386) ثباتهای عمومی به صورت زیر معرفی میشوند كه 36 بیتی میباشند:

EAX, EBX, ECX, EDX

در ثباتهای اشاره گر به صورت:

EDI, ESI, ESP, EBP, EIP

در ثباتهای سگمنت به صورت:

FS, GS


برای دیدن رجیسترها در DEBUG ,DOSرا اجرا كنید و فرمان R را صادر كنید :


D:\MASM>DEBUG

-R

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000

DS=17AA ES=17AA SS=17AA CS=17AA IP=0100 NV UP EI PL NZ NA PO NC

17AA:0100 0F

حافظه و آدرس دهی


هر كامپیوتر مبتنی بر 8086 دارای حداقل 640 كیلوبایت حافظه است . این 640

كیلوبایت به قطعات 64 كیلوبایتی تقسیم شده و ما این قطعات را "قطعه " یا Segment

مینامیم . هر سگمنت هم به خانه های تك بایتی دیگری تقسیم شده است .


برای بدست آوردن مقدار یك بایت مشخص از حافظه ما باید عدد مربوط به سگمنت و

همچنین شماره آن بایت در سگمنت ( كه آفست Offset نامیده میشود-چندمین خانه از شروع سگمنت ) را بدانیم .

مثلا اگر مقدار مورد نظر در قطعه 0030h( یعنی عدد در مبنای 16 است ) و آفست 13C4h

باشد ما باید قطعه ای كه شماره آن 0030h است را بیابیم و بعد در همان قطعه

مقدار بایت شماره 13C4 را بخوانیم .

برای نمایش این حالت بین عدد سگمنت و آفست علامت ( : ) قرار میدهیم . یعنی

ابتدا عدد مربوط به قطعه را نوشته و سپس عدد آفست را می آوریم :

Segment: Offset

همیشه در آدرس دهی ها از اعداد مبنای 16 استفاده میكنیم .

مثال:

1234H:5678H

برای به دست آوردن آدرس فیزیكی جلوی آدرسBase یك صفر میگذاریم و با آفست جمع میزنیم.


12340+5678=179B8H


دستورهای اجرایی اسمبلی

حالا میخواهیم به رجیتسرها مقدار بدهیم و آنها را بخوانیم و ... . ما معمولا در

زبانهای دیگر از علامت

=(یا =ا

برای مقدار دهی استفاده میكنیم ولی در زبان

اسمبلی این كار ممكن نیست . در عوض از دستورالعمل MOV كمك میگیریم . با MOV

میتوانیم داده ها را بین رجیسترها یا خانه های حافظه انتقال بدهیم . به این صورت :

MOV D/S

مقادیری كهDمیتوانند بگیرنند یك رجیستر، نام یك متغیر، یا آدرس یك مكان از حافظه است و مقادیری كهS میتواند بگیردهم یك مقدار عددی یا حرفی ، نام یك رجیستر و ... میباشد .(cte=مقدار ثابت)


registe register

register --> memory

memory --> register

register -->cte

memory -->cte

segment register --> general register

general register -->segment register


حالت های غیر ممكن:

segment register -->segment register

segment register --> cte

؟ ‹--- ثابت


باز هم باید به یك یا دوبایتی بودن ثباتها توجه كنیم . به عبارت دیگر ما

نمیتوانیم مقدار یك ثبات تك بایتی را به یك ثبات كامل دوبایتی منتقل كنیم .

مثلا عبارت mov DX/AL قابل قبول نیست چون AL یك بایتی بوده و DX دوبایتی است .

به عبارت ساده و كامل تر دو طرف عملوند MOV باید از نظر اندازه برابر باشند.

بنابر این :

MOV DL/AL

و MOV CL/BHوM درست ولی MOV DS/AH نادرست است .

 

به علاوه ما فقط میتوانیم ثباتهای همه منظوره AXتا DX را به این صورت مقدار دهی

كنیم . در صورتی كه بخواهیم ثباتهائی مثل ..DS/ES/ را مقدار دهی كنیم باید از

رجیستر AX به عنوان واسطه استفاده كرده و مقدار را از طریق آن انتقال دهیم .

مثلا:

نمیتوانیم بنویسیم mov ds/20h

ولی میتوانیم داشته باشیم :

mov ax/20h

mov ds/ax

 

به این ترتیب مقدار 20hبه DS انتقال پیدا میكند ( گرچه تغییر دادن DS ایده خوبی

نیست !)


حالا مطالب گفته شده را تمرین میكنیم . ما میتوانیم با DEBUG اسمبلی بنویسیم و

حتی برنامه های COM. درست كنیم . بنا براین در DOS، DEBUG، را اجرا كنید .

D:\LNG\ASM> DEBUG

 

یك خط تیره به صورت - ظاهر میشود . این خط تیره اعلان DEUBG برای وارد كردن

دستورات است .

حرف A (به معنی شروع وارد كردن دستورات اسمبلی ) را وارد كرده و Enter را بزنید .

عددی بصورت xxxx:0100 ظاهر میشود . این عدد برای شما (فعلا) مهم نیست ، پس به

آن توجه نكنید .

حالا میتوانید دستورات زیر را وارد كنید :

 

MOV AX/100

MOV BX/AX

MOV ES/AX

 

بعد از وارد كردن خط آخر یكبار دیگر كلید Enter را بزنید تا اعلان (-) دوباره ظاهر

شود .

در سطر اول ما عدد 100h ( پیش فرض اعداد در Debug هگزا است ) را به AX منتقل

كردیم . بعد مقدار AXبه BX و سپس مقدار AXبه ES منتقل شده . به این ترتیب همه

ثباتهای AX/BX/ES باید در نهایت برابر 100h باشند .

برای دیدن صحت این مطلب دستور T ( به معنای Trace) را وارد كنید .

با هر بار اجرای این دستور یكی از سطرهای برنامه اجرا میشود . بعلاوه شما میتوانید

محتوای رجیسترها را هم ببینید .

با اولین فرمان T ، سطر اول اجرا میشود . بازهم فرمان T را وارد كنید . الان مقدار100h

به BX داده شد و اگر به محتوای رجیستر AX توجه كنید خواهید دید كه مقدار آن

(همانطور كه انتظار داشتیم ) برابر 100h است . دوبار دیگر هم فرمان T را صادر

كنید و در نهایت مقدار ثباتهای AX/BX/ES را ببینید . هر سه ثبات (حالا) برابر 100h

هستند .

برای خارج شدن از Debug هم فرمان Q به معنی Quit را وارد كنید .

 

حالا فرض كنید با این آدرس روبرو شدید MOV [200H]/70H

این دو از حافظه هستند پس چه جوری باید مقدار را منتقل كنیم؟؟

خیلی راحت با استفاده از دستورPTR؛ برای اینكه آدرس یك متغیر بیان كننده نوع آن متغیر نمیباشد(یعنی چند بایتی است) از عملگر PTR استفاده میشود.


BYTE PTR [......]

WORD PTR [......]

DWORD PTR [......]


MOV BYTE [200H]/70H.

مثال) كدامیك از دستورات زیر درست میباشد؟

1) MOV BYTE PTR[DI]/BL

MOV BYTE PTR[SI]/300(2

MOV BYTE PTR[SI]/BYTE PTR[DI] (3

MOV [300H]/ BX (4


حل:

گزینه 2و3 غلطه؛چرا

2- چون 300 بیشتر از یك بایت است

3- انتقال از حافظه امكان ندارد


توضیحی درباره ی رجیستر وضعیت و كنترل(status& contorol register):

CF: carry flat

ZF: zero flag

PF: paritty flag

اگر نتیجه محاسبه صفر باشدZF؛یك میشود واگر نتیجه صفر نشد؛این بیت صفر میشود

AF: پرچم نقلی كمكی=اگر درموقع محاسبه از بیت 3به4 رقم نقلی داشته باشیم این بیت یك میشود.

PF: پرچم تقارن= اگر تعداد 1های نتیجه زوج باشدPF-1میباشد و اگر تعداد یكهای نتیجه فرد باشدPF=0میشود.

SF: پرچم بیت علامت.اگر نتیجه منفی باشدSF=1واگر تنیجه مثبت باشدSF=0میشود.

OF:پرچم سرریز.اگر تنیجه محاسبه خیلی بزرگ یا خیلی كوچك باشد كه در مقدار پیشبینی شده جا نشود؛سرریز اتفاق می افتد و OF=1میشود.


دستورات اسمبلی:

دستورات انتقال داده:دستور MOVرو قبلا گفتم.در اینجا دستورهای LEA ,XCHG رو بررسی میكنیم.

XCHG:این دستور محتوای D,Sرا با هم عوض میكند.

XCHG D,S

D<==>S

Genelar register <==> general register

general register<==> memory

memory<==>general register

در این دستور یك طرف حتماً باید رجیسترباشد.

+ نوشته شده در جمعه 1386/03/25ساعت 16:45 توسط iaxxoi | آرشیو نظرات
درباره
 
به سبب اینکه سایت Opera اکانتی رو که فایل ها در اون آپلود می شد رو قفل کرده (به دلیل نقض قانون حق مولفین "Copy right" یا هر دلیل دیگه ای) ممکنه تعدادی از فایل های این وبلاگ قابل دسترسی نباشند که به مرور سعی می شود لینک ها اصلاح شوند. در صورت لزوم با آدرس ایمیلی که در آخر صفحه درج شده می توانید تماس بگیرید.





.: Weblog Themes By Pichak :.


شرکت کوشا الکام پارس نماینده رسمی اینترنت پرسرعت شاتل در کازرون * سرعت فوق العاده * ادرس:چهار راه بانک ملی مجتمع تجاری کوثر واحد 1 * تلفن:11-2219410

اللّهُمَّ كُنْ لِوَلِیِّكَ الْحُجَّةِ بْنِ الْحَسَنِ صَلَواتُكَ عَلَیْهِ وَعَلى آبائِهِ فی هذِهِ السّاعَةِ وَفی كُلِّ ساعَةٍ وَلِیّاً وَحافِظاً وَقائِدا ‏وَناصِراً وَدَلیلاً وَعَیْناً حَتّى تُسْكِنَهُ أَرْضَك َطَوْعاً وَتُمَتِّعَهُ فیها طَویلاً

Google

در این وبلاگ
در كل اینترنت

دریافت کد قلب دنبال موس
تمامی حقوق این وبلاگ محفوظ است
قالب وبلاگقالب وبلاگ
تحلیل آمار سایت و وبلاگ