<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Iran Developers Network &#187; اسمبلی &#8211; Assembly</title>
	<atom:link href="http://www.irandevelopers.com/category/programming/assembly/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.irandevelopers.com</link>
	<description>IDN بزرگترین مرجع توسعه دهندگان ایران - آموزش زبانهای برنامه نويسی</description>
	<lastBuildDate>Mon, 23 Aug 2010 08:51:43 +0000</lastBuildDate>
	<language>fa</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>بدست آوردن طول رشته در اسمبلی</title>
		<link>http://www.irandevelopers.com/programming/assembly/stringlen-assemb-2112/</link>
		<comments>http://www.irandevelopers.com/programming/assembly/stringlen-assemb-2112/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 19:22:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/uncategorized/-2112/</guid>
		<description><![CDATA[با استفاده از کد زیر می توانید طول رشته را در زبان برنامه نویسیassembly به دست اورید strlen proc      ; find the length of a ASCIIZ string push cx        ; input : ES:di point to string push di        ; output: ax =  string length mov cx,0FFFFh mov al,0 cld repnz scasb dec di mov ax,di [...]]]></description>
			<content:encoded><![CDATA[<p>با استفاده از کد زیر می توانید طول رشته را در زبان برنامه نویسیassembly به دست اورید</p>
<p>strlen proc       ; find the length of a ASCIIZ string</p>
<p>push cx        ;  input : ES:di point to string</p>
<p>push di        ; output: ax =  string length</p>
<p>mov cx,0FFFFh</p>
<p>mov al,0</p>
<p>cld</p>
<p>repnz scasb</p>
<p>dec di</p>
<p>mov ax,di</p>
<p>pop di</p>
<p>sub ax,di</p>
<p>pop cx</p>
<p>ret</p>
<p>strlen endp</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/assembly/stringlen-assemb-2112/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یاد بگیریم &#8211; ۱۵</title>
		<link>http://www.irandevelopers.com/programming/learnassemblyp158710252113-1220/</link>
		<comments>http://www.irandevelopers.com/programming/learnassemblyp158710252113-1220/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 17:43:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1220</guid>
		<description><![CDATA[در قسمت قبلی چند عملگر بیتی را دیدیم . در این قسمت هم این مبحص را دنبال میکنیم . عملگر Not : عملوند Not ارزش همه بیتهای یک بایت یا کلمه را برعکس میکند . یعنی تمام بیتهای ۱را ۰ا و تمام بیتهای ۰را ۱ا میکند . بعنوان مثال اگر AH حاوی مقدار ۱۰۱۰۱۱۰۱ باشد، [...]]]></description>
			<content:encoded><![CDATA[<p>در قسمت   قبلی  چند عملگر بیتی  را دیدیم  . در این  قسمت   هم  این  مبحص   را دنبال<br />
میکنیم  .<br />
عملگر Not : عملوند Not ارزش   همه  بیتهای  یک   بایت   یا کلمه  را برعکس   میکند .<br />
یعنی  تمام  بیتهای  ۱را ۰ا و تمام  بیتهای  ۰را ۱ا میکند . بعنوان  مثال  اگر AH حاوی<br />
مقدار ۱۰۱۰۱۱۰۱ باشد، بعد از اجرای  Not Al ، محتوای  AL بصورت   ۰۱۰۱۰۰۱۰ خواهد<br />
بود.</p>
<p>جدول  ارزشی  Not                    Not X  X N<br />
F  |   T<br />
T  |   F</p>
<p>عملگر Neg . این  اپراتور معمولا با Not اشتباه  میشود در صورتی  که  کمتر شباهتی  بین<br />
آنها وجود دارد . Neg ارزش   عددی  یک   عدد علامتدار را برعکس   میکند . یعنی  یک   عدد<br />
منفی  را مثبت   میکند و برعکس   . در اعداد علامتدار ( همانطور که  بعدا هم  خواهیم<br />
دید )، اولین  بیت   سمت   چپ   ( بیت   هشتم  ) بیت   علامت   است   . ۱ بودن  آن  نشاندهنده<br />
منفی  بودن  و ۰ بودن  آن  نشان  دهنده  مثبت   بودن  است   .<br />
عملگر Neg با عکس   کردن  بیت   علامت   ، ارزش   عدد را عکس   میکند .<br />
این  عملوند را در مبحث   اعداد علامتدار مفصلا میخوانیم  .<br />
مثال  : میخواهیم  برنامه  ای  بنویسیم  که  تمام  حروف   کوچک   یک   عبارت   را به  حروف<br />
بزرگ   تبدیل  کند . از نظر مقدار عددی  ، تفاوت   حروف   کوچک   و بزرگ   در اینست   که<br />
بیت   پنجم  در حروف   بزرگ   برابر ۰ و در حروف   کوچک   ۱ است   . مثلا کداسکی  حرف   a<br />
به  باینری  برابر ۰۱۱۰۰۰۰۱ و کد A برابر ۰۱۰۰۰۰۰۱ است   . پس   برنامه  ای  مینویسیم<br />
که  تمام  کاراکترهای  رشته  کاراکتری  مورد نظر را خوانده  و بیت   پنچم  آنها را ۰ کند<br />
. در قسمت   قبلی  دیدیم  که  برای  ۰ کردن  یک   بیت   ، یک   عدد باینری  که  تمام  بیتهای<br />
آن  ۱ ، و بیت   مورد نظر (برای  ۰ کردن  ) ۰ باشد را با عدد مورد نظر AND میکنیم  .</p>
<p align="left">.   MODEL SMALL<br />
.   CODE<br />
ORG 100H<br />
START                                            :<br />
JMP MAIN<br />
MSG DB &#8216; this is an example/ ..$&#8217;<br />
MAIN                                                :</p>
<p>بدست آوردن آدرس رشته ; LEA BX/MSG LOOP :_</p>
<p>قرار دادن  کارکتر در  AL                         ;         MOV AL/[BX]<br />
آیا کاراکتر $ است  ?                             ;          CMP AL/&#8217;$&#8217;<br />
بله  ، به   MAIN  برو                             ;             _JZ END<br />
بیت   پنجم  را صفر کن                              ;  AND [BX]/11011111B<br />
یکواحد به BX اضافه کن &#8211; کاراکتر بعدی ; INC BX JMP LOOP _;<br />
END                                     :_</p>
<p>قرار دادن  آفست   رشته  در  DX                     ;           MOV DX/BX<br />
تابع  ۹ برای  نمایش   رشته                          ;            MOV AH/9<br />
قفه  ۲۱h                                        ;             INT 21H<br />
پایان  برنامه                                     ;             INT 20H        END START</p>
<p>معمولا برنامه  هائی  که  پیغامهای  خود را کد میکنند ( مثل  ویروسها ) از این  روش   یا<br />
روشی مشابه برای Decode کردن پیغامها استفاده میکنند .</p>
<p>مثال  :<br />
بایت   وضعیت   صفحه  کلید که  مربوط به  وضعیت   کلید های  کنترلی                 CapsLock/NumLock<br />
در بایوس   های  AT/PS2 در آدرس   ۰۰۱۷h:0040h قرار دارد.<br />
بیتهای  این  بایت   نشان  میدهد که  کدام  کلید  فعال  است   . ۱ بودن  به  معنی  روشن  بودن<br />
و ۰ به  معنی  خاموش   بودن  آن  است   . در مثال  زیر بیت   ششم  برای  کلید CapsLockرا ۱ا<br />
میکنیم تا Capslock روشن شود .<br />
.MODEL SMALL<br />
.CODE<br />
ORG 100h<br />
START:<br />
PUSH ES<br />
MOV AX/0040h<br />
MOV ES/AX<br />
MOV AL/ES:[17h]<br />
OR AL/32<br />
MOV BYTE PTR ES:[17h]/AL<br />
POP ES<br />
MOV AH/1<br />
INT</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassemblyp158710252113-1220/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یاد بگیریم &#8211; ۱۴</title>
		<link>http://www.irandevelopers.com/programming/learnassemblyp148710252111-1218/</link>
		<comments>http://www.irandevelopers.com/programming/learnassemblyp148710252111-1218/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 17:41:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1218</guid>
		<description><![CDATA[عملگرهای بیتی عملگرهای بیتی مانند عملوندهای حسابی هستند با این تفاوت که روی بیت ها کار میکنند. این عملگرها عبارتند از : &#8230; AND/OR/XOR/SHR/SHL/RCL/RCR/ . عملگر AND : این اپراتور بیتهای دو عدد(متغیر) را با هم AND کرده و حاصل را در متغیر (یا ثبات ) سمت چپ قرار میدهد . اگر فرض کنیم که [...]]]></description>
			<content:encoded><![CDATA[<p>عملگرهای بیتی</p>
<p>عملگرهای  بیتی  مانند عملوندهای  حسابی  هستند با این  تفاوت   که  روی  بیت   ها کار<br />
میکنند. این  عملگرها عبارتند از :   &#8230; AND/OR/XOR/SHR/SHL/RCL/RCR/ .</p>
<p>عملگر AND : این  اپراتور بیتهای  دو عدد(متغیر) را با هم  AND کرده  و حاصل  را در<br />
متغیر (یا ثبات  ) سمت   چپ   قرار میدهد . اگر فرض   کنیم  که  همیشه  ۱ بودن  بیت  به<br />
معنای  Trueو ۰و بودن  آن  به  معنای  False است   ، AND همیشه  در صورتیکه  هر دوبیت<br />
مقایسه  شونده  ۱ باشند، حاصل  ۱یا Trueا را بر میگرداند .<br />
جدول  ارزشی  AND :<br />
X | Y |  X and Y |</p>
<p>1 | 1 |    1     |<br />
1 | 0 |    0     |<br />
0 | 1 |    0     |<br />
0 | 0 |    0     |</p>
<p>پس   وقتی  ما عملوند AND را با دو رجیستر بکار میبریم  ، بصورتی  که  گفته  شد بیتها<br />
با هم  مقایسه  شده  و حاصل  مقایسه  در محل  متناظر بیتها در ثبات   سمت   چپ   قرار<br />
میگیرند . مثلا اگر دستور AND Ah/Dh را اجرا کنیم  ، حالتی  نظیر شکل  زیر را داریم :<br />
AH    : 01101010<br />
DH    : 01111101</p>
<p>AH :AH AND DH : 01101000</p>
<p>به  نتیجه  بدست   آمده  توجه  کنید .<br />
هر وقت   که  بخواهیم  بیت   های  خاصی  از یک   رجیستر را ۰ کنیم  ، یک   عدد باینری  که<br />
همه  بیتهای  آن  ، بجز بیتهای  مورد نظر ۱ هستند را در نظر گرفته  با رجیستر مورد نظرAND<br />
میکنیم .مثلا اگر بخواهیم بیتهای دوم و سوم ثبات AX را صفر کنیم : AND AX/11111001b</p>
<p>عملگر OR :<br />
این  عملوند بیتهای  دو عدد را با هم  مقایسه  کرده  و اگر یکی  از آن  دو ۱ بود ، بیت<br />
متناظر در ثبات   سمت   چپ   را ۱ میکند . مثلا با دستور OR AH/DH بیتهای  AHبا DHا<br />
مقایسه شده و هر دو بیت متناظر که با هم ۰ بودند ، بیت تناظر در AHهم ۰ میشود<br />
AH    : 01101010<br />
DH    : 01111100</p>
<p>AH : AH OR DH : 01111110</p>
<p>هرگاه  که  بخواهیم  بیت   های  خاصی  از یک   متغیر یا رجیستر را ۱ کنیم  ، یک   عدد<br />
باینری  که  همه  بیتهای  آن  غیر از بیتهای  مورد نظر ۰ هستند در نظر گرفته  و با ثبات<br />
مورد نظر OR میکنیم  . مثلا اگر بخواهیم  دو بیت   پائین  AHرا ۱ا کنیم  منویسیم :         OR AH/00000011b</p>
<p>عملگر : XOR<br />
عملوند XOR تنها در صورتی  نتیجه  ۱ میدهد که  دو بیت   مقایسه  شونده  غیرهم  ارزش<br />
باشند . یعنی  یکی  ۱ و دیگری  ۰ باشد .<br />
بعنوان مثال با اجرای XOR AH/DH این عملیات روی بیتها انجام میشود<br />
AH    : 01101010<br />
DH    : 01111100</p>
<p>AH : AH XOR DH : 11101001</p>
<p>وقتی  بخواهیم  یک   مقدار ثبات   را برابر صفر قرار بدهیم  ، معمولا از آن  را با خودش  XOR<br />
میکنیم . مثلا XOR CX/CX محتوای ثبات CX را برابر ۰ قرار میدهد .</p>
<p>عملگرهای SHRو SHLو :</p>
<p>این  عملگرها، بیتها را به  راست   و چپ   شیفت   ( انتقال ) میدهند .<br />
SHR Reg.nnum           و  SHL Reg.nnum<br />
.Reg اسم  یک   ثبات   است   مثلا AXو numو معلوم  میکند که  چند بیت   باید به  طرف<br />
راست   یا چپ   انتقال  پیدا کند . مثلا SHR AX/6 بیتهای  AXرا ۶ا واحد به  راست<br />
انتقال  داده  و بیتهای  چپ   را با ۰ پر میکند .                                                        AX :10100010<br />
AX :SHR AX/4 :  00001010</p>
<p>SHL<br />
هم  عکس   این  عمل  را انجام  میدهد . یعنی  بیتها را به  چپ   شیفت   داده  و از<br />
طرف راست با ۰ پر میکند . AX :10100010<br />
AX :SHR AX/4 :  00100000</p>
<p>مثال  : اگر بخواهیم  که  محتوای  نیم  ثبات   CL را به  نیم  ثبات   CH منتقل  کنیم ،<br />
کافیت که CXرا ۸ا بیت به سمت چپ شیفت بدهیم . یعنی SHL CX/8</p>
<p>CL             CH                                                          |  10110100     |    00101101  |</p>
<p>محتوای اولیه CX CX</p>
<p>CL             CH                                                          |  00101101     |    00000000  |</p>
<p>محتوای  CX بعد از                   SHL CX/8<br />
انتقال</p>
<p>ادامه  این  بحث   را در قسمت   بعد انجام  میدهیم  .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassemblyp148710252111-1218/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یلد بگیریم &#8211; ۱۳</title>
		<link>http://www.irandevelopers.com/programming/learnassemblyp138710252110-1216/</link>
		<comments>http://www.irandevelopers.com/programming/learnassemblyp138710252110-1216/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 17:41:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1216</guid>
		<description><![CDATA[در این قسمت یک تمرین جدید انجام داده و بوسیله آن تجربیات خودمان را افزایش میدهیم . این تمرین اولین برنامه ما هست یک عملیات سطح پائین سیستم ، یعنی دسترسی به دیسک ، را انجام میدهد . تابع شماره ۲(AH=2() از وقفه ۱۳h که وقفه دیسک میباشد ، برای خواندن سکتورهای دیسک بکار میرود [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: right;">در این  قسمت  یک   تمرین  جدید انجام  داده  و بوسیله  آن  تجربیات   خودمان  را افزایش<br />
میدهیم  . این  تمرین  اولین  برنامه  ما هست  یک   عملیات   سطح  پائین  سیستم  ، یعنی<br />
دسترسی  به  دیسک   ، را انجام  میدهد .</p>
<p>تابع  شماره  ۲(AH=2() از وقفه  ۱۳h که  وقفه  دیسک   میباشد ، برای  خواندن  سکتورهای<br />
دیسک   بکار میرود . وقتی  شماره  هد، شیار،سکتور و &#8230; را مشخص   کرده  و وقفه  را<br />
فراخوانی  نمودیم  ، محتوای  قطاع خوانده  شده  در محلی  که  با جفت   ثبات   ES:BX مشخص<br />
میشود قرار میگیرد. به  همین  دلیل  ما یک   آرایه  تعریف   میکنیم  وآدرس   آن  را در    ES:BX<br />
قرار میدهیم تا اطلاعات خوانده شده در آن قرار بگیرد. BUF DB 512 DUP(0)</p>
<p>در این  مثال  ما میخواهیم  برنامه  ای  بنویسیم  که  محتوای  قطاع بوت   کننده  دیسکی  را<br />
خوانده  و نمایش   دهد . چون  میخواهیم  یک   سکتور را بخوانیم  و اندزه  هر قطاع ۵۱۲<br />
بایت   است  ، پس   آرایه  ای  با ۵۱۲ عنصر تک   بایتی  تعریف   کرده  ایم  .<br />
در قدم  بعدی  شماره  شیار (۰-۷۹) را در CH، شماره  قطاع (۱-۱۸) را در CL، شماره<br />
درایو را در DL(&#8230;/.:0=A ) ، رویه  دیسک   را در DH(0=1st Side() و تعداد قطاعهائی<br />
که  باید خوانده  شوند را در AL قرار میدهیم  .</p>
<div dir="ltr">
<p align="left">MOV AX/0201H<br />
MOV CH/0        ;TRACK NUMBER<br />
MOV CL/1        ;SECTOR NUMBER<br />
MOV DH/0        ; SIDE #1<br />
MOV DL/0        ; 0=A / 1=B /( &#8230;DRIVE NUMBER )</p>
</div>
<p>حالا باید آدرس   بافر تعریف   شده  (BUF) را به  ES:BX منتقل  کنیم  . گفتیم  که  برای<br />
بدست   آوردن  شماره  سگمنت   هر متغیر از Seg و برای  بدست   آوردن  مقدار آفست   از    Offset<br />
استفاده  میکنیم  . چون  برنامه  ما COM. است  ، پس   عدد سگمنت   بطور خودکار در<br />
ثبات   DS هست   و احتیاجی  به  یافتن  آن  نداریم  . بلکه  فقط باید آن  را به  ES منتقل<br />
کنیم  .<br />
گفتیم  که  نمیتوانیم  ثبات   ESو DSو را مستقیما و با MOV به  هم  منتقل  کنیم  ، بلکه<br />
باید از یک   ثبات   همه  منظوره  مثل  AX کمک   بگیریم  . بنا براین  و برای  اینکه  مقدار<br />
فعلی  ثبات   AX از بین  نرود، ابتدا AX را در Stack قرار داده  و مقدار DS را در آن<br />
قرار میدهیم  :                                                                             PUSH AX         ; SAVE AX<br />
MOV AX/DS</p>
<p>و پس   از آن  محتوای  AX را به  ES داده  و دوباره  مقدار AX را از پشته  POP میکنیم :              MOV ES/AX<br />
POP AX</p>
<p>پس از آن با دستور LEA مقدار آفست BUF را بدست می آوریم : LEA BX/BUF</p>
<p>و در نهایت فراخوانی اینتراپت ۱۳h. INT 13H</p>
<p>بقیه  برنامه  عبارتست   از چاپ   کارارکترهای  داخل  آرایه  BUF که  قبلا آن  را یاد<br />
گرفتیم  . فقط به  این  نکته  توجه  میکنیم  که  کدهای  اسکی  کوچکتر از ۳۲ کدهای  کنترلی<br />
بوده  و به  جای  آنها باید کاراکتر (.) چاپ   کنیم  به  همین  دلیل  هم  قطعه  کدی  برای  آن<br />
نوشته  ایم  :</p>
<div dir="ltr">
<p align="left">
MOV AL/BUF[BX]<br />
CMP AL/32<br />
JB SKIP<br />
:<br />
:<br />
SKIP                            :<br />
MOV AL/&#8217;.&#8217;<br />
INT 10H<br />
:<br />
:</p>
</div>
<p>لیست   کامل  :                                                         .MODEL SMALL<br />
.CODE<br />
ORG 100H<br />
START:<br />
JMP MAIN<br />
BUF  DB 512 DUP(0)<br />
MAIN:<br />
MOV AX/0201H<br />
MOV CH/0        ;TRACK NUMBER<br />
MOV CL/1        ;SECTOR NUMBER<br />
MOV DH/0        ; SIDE #1<br />
MOV DL/0        ; 0=A / 1=B /( &#8230;DRIVE NUMBER)<br />
PUSH AX         ; SAVE AX<br />
MOV AX/DS<br />
MOV ES/AX<br />
POP AX<br />
LEA BX/BUF<br />
INT 13H</p>
<p>MOV BX/1<br />
MOV AH/0EH      ; WRITE CHAR.<br />
PRINT:<br />
MOV AL/BUF[BX]<br />
CMP AL/32<br />
JB SKIP<br />
INT 10H<br />
JMP CONT<br />
SKIP:<br />
MOV AL/&#8217;.&#8217;<br />
INT 10H<br />
CONT:<br />
INC BX<br />
CMP BX/513<br />
JNZ PRINT<br />
INT 20H<br />
END START</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassemblyp138710252110-1216/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یاد بگیریم &#8211; ۱۲</title>
		<link>http://www.irandevelopers.com/programming/learnassemblyp128710211614-1185/</link>
		<comments>http://www.irandevelopers.com/programming/learnassemblyp128710211614-1185/#comments</comments>
		<pubDate>Sat, 10 Jan 2009 12:45:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1185</guid>
		<description><![CDATA[اسمبلی یاد بگیریم &#8211; ۱۲ در این قسمت نحوه دسترسی به مقادیر متغیر ها را یاد میگیریم . ے وقتی که میخواهیم مقدار یک متغیر را به یک متغیر یا ثبات دیگر منتقل کنیم باید ے به اندازه آن توجه داشته باشیم . مثلا اگر متغیری بصورت LOCATE DB 10 تعریف کرده ے باشیم ، [...]]]></description>
			<content:encoded><![CDATA[<p>اسمبلی  یاد بگیریم  &#8211; ۱۲</p>
<hr />
در این  قسمت   نحوه  دسترسی  به  مقادیر متغیر ها را یاد میگیریم  .<br />
ے  وقتی  که  میخواهیم  مقدار یک   متغیر را به  یک   متغیر یا ثبات   دیگر منتقل  کنیم  باید<br />
ے  به  اندازه  آن  توجه  داشته  باشیم  . مثلا اگر متغیری  بصورت   LOCATE DB 10 تعریف   کرده<br />
ے  باشیم  ، به  دلیل  تک   بایتی  بودن  ، نمیتوانیم  آن  را به  یک   ثبات   کامل  مثل  AX یا<br />
متغیر دوبایتی  که  با DW تعریف   شده  است   ارسال  کنیم  .<br />
ے اما انتقال آن به یک نیم ثبات مثل ALیا AHا و &#8230; مجاز است مانند . MOV BH/LOCATE</p>
<p>ے  از متغیرها بیشتر برای  نگهداری  موقت   داده  ها استفاده  میشود . مثلا وقتی  که<br />
ے  برنامه ای  برای  کار با قطاعهای  دیسک   مینویسیم  ، باید یک   محل  موقتی  برای  ذخیره<br />
ے  محتوای  قطاع های  خوانده  شده  ایجاد کنیم  . در این  موقع  یک   متغیر به  شکل (ترجیحا)<br />
آرایه  تعریف   میکنیم  .<br />
ے  وقتی  به  این  شکل  با متغیرها برخورد میشود، به  دانستن  آدرس   آن  نیاز پیدا میکنیم<br />
فرض   کنید میخواهیم  جمله  A QUICK START TO ASSEMBLY PROGRAMMING  را چاپ   کنیم  .<br />
در قدم  اول  باید متغیری  تعریف   کرده  و این  جمله  را داخل  آن  قرار دهیم  .<br />
پس : MSG DB &#8216;A QUICK START TO ASSEMBLY PROGRAMMING&#8217;/13/10/&#8217;$&#8217;</p>
<p>ے  اعداد ۱۳وَ۱۰ انتهای  رشته  برای  انتقال  مکان  نما به  سطر بعد هستند و کاراکتر &#8216;$&#8217;<br />
ے  از این  جهت   وجود دارد که  تابع  چاپ   رشته  انتهای  رشته  کاراکتری  را با بودن  $<br />
تشخیص   میدهد.<br />
ے  برای  چاپ   رشته  کاراکتری  راه  هائی  وجود دارد که  یکی  از آنها استفاده  از تابع  ۹h<br />
مربوط به  INT 21h میباشد .<br />
برای فراخوانی آن باید به این صورت رجیستر ها را پر کنیم : AH=09H</p>
<p>آدرس رشته کاراکتری DS:DX = INT 21H</p>
<p>ے  عبارت   DS:DX نشان  میدهد که  مقدار قطعه  (Segment) رشته  کاراکتری  ، یعنی  آن  قطعه<br />
ے  ای  که  متغیر تعریف   شده  در آن  قرار گرفته  است   ، را باید در DS قرار بدهیم  . به<br />
همین  صورت   نیز مقدار آفست   (Offset) آن  را به  DX انتقال  میدهیم  .<br />
برای  بدست   آوردن  شماره  قطعه  یک   متغیر از عملگر SEG استفاده  میکنیم  .<br />
ے  مثلا برای  بدست   آوردن  شماره  قطعه  MSGاز MOV AX/Seg MSGز استفاده  میکنیم  . این<br />
دستور شماره  سگمنت   MSG را پیدا کرده  و در AX قرار میدهد .<br />
برای  بدست   آوردن  شماره  آفست   هم  از OFFSET استفاده  میکنیم  مثلا MOV DX/OFFSET MSG<br />
پس برای چاپ رشته MSG باید به این صورت عمل کنیم :</p>
<div dir="ltr">
<p align="left">MOV AH/09H<br />
MOV DX/OFFSET MSG<br />
INT 21H</p>
</div>
<p>ے  این  قطعه  کاری  که  ما میخواهیم  را انجام  میدهد و اگر دقت   کنید متوجه  میشوید که<br />
ے  اصلا شماره  قطعه  (Segment) را محاسبه  نکرده  ایم  . علت   اینست   که  متغیر ما به  دلیل<br />
ے  COM. بودن  برنامه  در Code Segment ( که  با CODE. مشخص   میشود) تعریف   شده  پس   خود<br />
ے  بخود DS حاوی  مقدار سگمنت   آن  هست   . ( باز هم  یاد آوری  میکنیم  که  CS حاوی  شماره<br />
ثبات کد و DS حاوی ثبات داده ها است و در برنامه های COM. مقدار برابر دارند)</p>
<p>ے  یک   دستور خلاصه  برای  بدست   آوردن  عدد آفست   وجود دارد بنام  LEA .کل  کاری  که  این<br />
ے  دستورالعمل  انجام  میدهد اینست   که  دیگر احتیاج  به  نوشتن  OFFSET نخواهد بود . به<br />
عنوان  مثال  MOV DX/OFFSET MSGبا LEA DX/MSGا برابر است   .<br />
با این  تفاسیر کل  برنامه  به  این  شکل  خواهد بود .</p>
<div dir="ltr">
<p align="left">.            MODEL SMALL<br />
.            CODE<br />
ORG 100H<br />
START                                                              :<br />
JMP MAIN      ; skip to main codes<br />
MSG DB &#8216;A QUICK START TO ASSEMBLY PROGRAMMING&#8217;/13/10/&#8217;$&#8217;<br />
MAIN                                                               :<br />
LEA DX/MSG    ; get MSG offset<br />
MOV AH/09     ; write string function<br />
INT 21H       ; call interrupt 21h<br />
INT 20H       ; terminate program<br />
END START</p>
</div>
<p>تمرین  :<br />
ے  برای  اینکه  تمرین  بهتری  داشته  باشیم  ، میخواهیم  خودمان  و فقط با استفاده  از وقفه<br />
ے  مربوط به  چاپ   کاراکتر همین  جمله  را چاپ   کنیم  . قبلا گفتیم  که  تابع  ۰Eh از وقفه<br />
ے  ۱۰h یک   کاراکتر را در محل  مکان  نما چاپ   کرده  و مکان  نما را یک   خانه  به  راست<br />
انتقال  میدهد. میخواهیم  رشته  کاراکتری  بالا را تا رسیدن  به  علامت   $ چاپ   کنیم  .<br />
ے  بهترین  کار اینست   که  عدد آفست   را در BX قرار بدهیم  . در اینموقع  آفست   اولین<br />
ے  کاراکتر در BX است   . مقدار داخل  این  آفست   را بصورت   MOV al/[bx] به  ثبات   AL<br />
ے  منتقل  کرده  و بعد چاپ   میکنیم  . برای  کاراکتر بعدی  یکواحد به  BX اضافه  میکنیم  و<br />
ے  دوباره  همان  کارهای  قبلی &#8230; . این  عملیات   را باید تا رسیدن  به  کاراکتر &#8216;$&#8217; ادامه<br />
بدهیم  .<br />
ے   ** این  برنامه  را خودتان  و بدون  توجه  به  راه  حل  ارائه  شده  بنویسید و فایل  COM.<br />
آن  را بسازید.<br />
.            MODEL SMALL<br />
.            CODE<br />
ORG 100H<br />
START                                                              :<br />
JMP MAIN        ; jump to MAIN<br />
MSG DB &#8216;A QUICK START TO ASSEMBLY PROGRAMMING&#8217;/13/10/&#8217;$&#8217;<br />
MAIN                                                               :<br />
LEA BX/MSG      ; get MSG offset<br />
MOV AH/0EH      ; write char function<br />
LOOP                                                               :_<br />
MOV AL/[BX]     ; move [BX] to AL: charactre code<br />
CMP AL/&#8217;$&#8217;      ; if al is equal with &#8216;$&#8217;<br />
JE END         _; then jump to END                             _<br />
INT 10H         ; otherwise call interrupt 10h<br />
INC BX          ; BX=BX+1<br />
JMP LOOP       _; jump to next caharcter<br />
END                                                                :_<br />
INT 20H         ; terminae program<br />
END START</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassemblyp128710211614-1185/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یاد بگیریم &#8211; ۱۱</title>
		<link>http://www.irandevelopers.com/programming/learnassemblyp118710211613-1183/</link>
		<comments>http://www.irandevelopers.com/programming/learnassemblyp118710211613-1183/#comments</comments>
		<pubDate>Sat, 10 Jan 2009 12:43:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1183</guid>
		<description><![CDATA[اسمبلی یاد بگیریم &#8211; ۱۱ حتما با ثابتها در زبانهائی مثل پاسکال آشنائی دارید . بعنوان مثال با جمله ے Const MaxLen=1024; ، ثابتی بنام MaxLen تعریف شده و مقدار آن برابر ۱۰۲۴ قرار ے قرار میگیرد . پس از آن کامپایلر در هرجا که MaxLen را مشاهده کند عدد ۱۰۲۴ را بجای آن قرار [...]]]></description>
			<content:encoded><![CDATA[<p>اسمبلی  یاد بگیریم  &#8211; ۱۱</p>
<hr />
حتما با ثابتها در زبانهائی  مثل  پاسکال  آشنائی  دارید .  بعنوان  مثال  با جمله<br />
ے   Const MaxLen=1024; ، ثابتی  بنام  MaxLen تعریف   شده  و مقدار آن  برابر ۱۰۲۴ قرار<br />
ے   قرار میگیرد . پس   از آن  کامپایلر در هرجا که  MaxLen را مشاهده  کند عدد ۱۰۲۴ را<br />
بجای  آن  قرار میدهد .<br />
در زبان اسمبلی برای تعریف یک ثابت از معرفه EQU به شکل زیر استفاده میکنیم</p>
<p>مقدار EQU نام  ثابت<br />
مثلا : MaxLen EQU 1024<br />
ے  به  این  ترتیب   اسمبلر همیشه  بجای  MaxLen عدد ۱۰۲۴ را قرار میدهد . بهمین  دلیل<br />
ثابتهای برنامه را باید قبل از جمله CODE. بنویسیم . مثال :</p>
<div dir="ltr">
<p align="left">.                  MODEL SMALL<br />
SECTORS EQU 18<br />
SIDES EQU 2<br />
.                  CODE<br />
:<br />
:</p>
</div>
<p>ے  به  این  خاطر ثابتها را قبل  از CODE. تعریف   میکنیم  که  در برنامه  کامپایل  شده  اثری<br />
از نام  ثابت   نبوده  بلکه  مقدار هر ثابت   در جای  لازم  قرار گرفته  است  .<br />
مثال  :</p>
<div dir="ltr">
<p align="left">. MODEL SMALL<br />
BELL EQU 7<br />
.          CODE<br />
ORG 100H<br />
MOV AH/0EH<br />
MOV AL/BELL<br />
INT 10H<br />
INT 20H<br />
END</p>
</div>
<p>متغیرها</p>
<p>ے   از متغیرها برای  نگهداری  موقتی  داده  ها استفاده  میکنیم  . مثلا در زبان  پاسکال<br />
ے   میتوانیم  با عبارت   Var یک   متغیر تعریف   کنیم  مثل  Var Buffer:Byte; و در زبان<br />
سی  مثل  unsigned char Buffer; .<br />
ے   متغیرها در زبان  اسمبلی  باید حتما در داخل  قطعه  داده  (DS) تعریف   بشوند و در<br />
ے   برنامه  های  COM. هم  از آنجائی  که  قطعه  داده  ها و کد یکی  است  میتوانیم  در قطعه  کد<br />
نیز تعریف   کنیم  .<br />
ے   برای  تعریف   یک   متغیر باید بعد از نام  آن  یکی  از عبارات   ..DB/DW/DD/ را<br />
ے   بیاوریم  . DB مشخصه  نوع بایت   ،DW مشخصه  نوع Word (دوبایتی ) و DD مشخصه  نوع<br />
(Double Word) 4 بایتی  است   .<br />
مثلا :</p>
<div dir="ltr">
<p align="left">. CODE<br />
SIZE DW 1024<br />
BELL DB 7</p>
</div>
<p>ے  در این  مثال  Size یک   متغیر دو بایتی  بوده  و مقدار اولیه  ان  ۱۰۲۴ است   و BELL نیز<br />
یک   متغیر تک   بایتی  با مقدار ۷ میباشد .<br />
ے  اگر نمیخواهیم  به  متغیر مقدار اولیه  بدهیم  ، میتوانیم  از علامت  (?) بجای  مقدار<br />
استفاده کنیم مانند : MaxLen DW ?</p>
<p>ے  برای  تعریف   یک   رشته  کاراکتری  از معرفه  DB استفاده  کرده  و محتوای  رشته  را داخل<br />
(&#8221;) یا (&#8220;&#8221;) قرار میدهیم  . مثلا :</p>
<div dir="ltr">
<p align="left">MSG DB &#8220;ASSEMBLY / A QUICK LOOK ! &#8220;</p>
</div>
<p>ے  در این  مثال  MSG یک   متغیر کاراکتری  است   . در اسمبلی  میتوانیم  از کد اسکی<br />
ے  کاراکتر ها نیز استفاده  کنیم  . مثلا اگر در تعریف   DB بخواهیم  کدهای  اسکی  ۱۳و ۱۰<br />
را به MSG اضافه کنیم میتوانیم با کاما این کار را انجام دهیم :</p>
<div dir="ltr">
<p align="left">MSG DB &#8220;ASSEMBLY / A QUICK LOOK ! &#8220;/13/10</p>
<p>یا : MSG DB &#8220;ASSEMBLY / A QUICK LOOK ! &#8220;/0Ah/0Dh</p>
<p>یا حتی : MSG DB &#8220;ASSEMBLY / A QUICK LOOK ! &#8220;/0Ah/0Dh/&#8217;$&#8217;</p>
</div>
<p>این ترکیبها همه یک رشته کاراکتری معرفی میکنند .</p>
<p>برای تعریف آرایه ها نیز از روشی مشابه و به شکل زیر استفاده میکنیم :</p>
<p>(مقدار اولیه )DUP تعداد عناصر  DB/DW/DD  نام  متغیر<br />
مانند: BUFFER DB 1024 DUP(0 )</p>
<p>که  ارایه  ای  یک   کیلوبایتی  تعریف   کرده  و همه  عناصر آن  را با ۰ پر میکند.<br />
اگر نخواهیم  مقدار اولیه  ای  در نظر گرفته  شود از ? استفاده  میکنیم  .<br />
مانند: BUFFER DB 1024 DUP(? )</p>
<p>و برای تعریف یک آرایه حرفی باید با یک حرف یا عبارت آن را پر کنیم : BUFFER DB 1024 DUP(&#8220;A&#8221; )</p>
<p>و حتی : BUFFER DB 1024 DUP(&#8220;STACK&#8221; )</p>
<p>ے  گفتیم  که  متغیرها همیشه  (در برنامه  های  COM.) در قطعه  کد و بعد از CODE. نوشته<br />
ے  میشوند ، بنا براین  اسمبلر همیشه  سعی  خواهد کرد که  آنها را بصورت   یک   کدماشین<br />
ے  قابل  اجرا تفسیر کند. به  همین  دلیل  همیشه  بایک   دستور JMP از روی  آنها پرش<br />
میکنیم  . مثال :</p>
<div dir="ltr">
<p align="left">
.      MODEL SMALL<br />
RDISK EQU 2<br />
.      CODE<br />
ORG1 100H<br />
START                                                                    :<br />
JMP MAIN<br />
BUFFER DB 512 DUP(0                                                  )<br />
MSG DB &#8220;DISK DUP.&#8221;/13/10/&#8217;$&#8217;<br />
MAIN                                                                      :</p>
</div>
<p>مجموعه  کدهای  اجرایی  برنامه                     :<br />
: END START</p>
<p>همانطور که میبینید با دستور JMP MAIN از قسمت تعریف داده ها پرش کرده ایم .</p>
<p>در قسمت   بعد نحوه  استفاده  از متغیرها و بافرها (Buffers) را مطالعه<br />
میکنیم  . با همین  معلومات   برنامه  ای  برای  نمایش   محتوای  سکتوهای  دیسک<br />
مینویسیم و پیغامهای لازم را به آن اضافه میکنیم .</p>
<p>پیروز باشید</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassemblyp118710211613-1183/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یاد بگیریم &#8211; ۱۰</title>
		<link>http://www.irandevelopers.com/programming/learnassemblyp108710211610-1181/</link>
		<comments>http://www.irandevelopers.com/programming/learnassemblyp108710211610-1181/#comments</comments>
		<pubDate>Sat, 10 Jan 2009 12:39:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1181</guid>
		<description><![CDATA[اسمبلی یاد بگیریم &#8211; ۱۰ در این قسمت یک تمرین دیگر با هم انجام میدهیم و برنامه ای مینویسیم که تعداد ۲۰۰ رنگ از ۲۵۶ رنگ موجود در حالت ۳۲۰&#215;۲۰۰ گرافیکی را نمایش دهد . تابع شماره ۰۰h از وقفه ۱۰h مربوط به تعیین حالت نمایش است . کد مربوط به حالت صفحه نمایش در [...]]]></description>
			<content:encoded><![CDATA[<p>اسمبلی  یاد بگیریم  &#8211; ۱۰</p>
<hr />
در این  قسمت   یک   تمرین  دیگر با هم  انجام  میدهیم  و برنامه  ای  مینویسیم  که  تعداد ۲۰۰<br />
رنگ   از ۲۵۶ رنگ   موجود در حالت   ۳۲۰&#215;۲۰۰ گرافیکی  را نمایش   دهد .<br />
تابع  شماره  ۰۰h از وقفه  ۱۰h مربوط به  تعیین  حالت   نمایش   است  . کد مربوط به<br />
حالت   صفحه  نمایش   در ثبات   AL قرار گرفته  و وقفه  فراخوانی  میشود:</p>
<p>شماره  تابع  برابر AH=00h<br />
حالت   صفحه  نمایش   با استفاده  از جدول  AL=          INT 10h</p>
<p>حالت   صفحه  نمایش   در AL از جدول  مخصوص   موجود در کتابهای  اسمبلی  بدست   می  آید.<br />
کد مربوط به  حالت   ۲۵۶C َ۳۲۰&#215;۲۰۰ برابر ۱۳h است   بنا براین  AL را برابر ۱۳h قرار<br />
میدهیم  .<br />
برای  نمایش   و روشن  کردن  یک   نقطه  (Pixel) در حالت   گرافیکی  از تابع  ۰Ch همین<br />
وقفه  استفاده  میکنیم  . یعنی  شماره  ستون  را در CX ، سماره  سطر را در DX و شماره<br />
رنگ   را در AL قرار داده  و وقفه  را اجرا میکنیم  . برای  اینکه  از ستون  ۱۹۹ تا ستون<br />
شماره  صفر نقطه  روشن  کنیم  ، CX را برابر ۳۱۹ قرار داده  و با دستور LOOP نقاط را<br />
در یک   سطر روشن  میکنیم  .</p>
<p align="left">
MOV CX/319      ; COLUMN 319 = START COLUMN<br />
COL:<br />
INT 10H         ; CALL INTERRUPT 10H<br />
LOOP COL</p>
<p>سپس   DX یا همان  شماره  سطر را یکواحد افزایش   میدهیم  و مقدار آن  را با ۱۹۹ مقایسه<br />
میکنیم  (چون  از ۰ تا ۱۹۹ سطر داریم ) و اگر برابر نبود دوباره  عملیات   بالا را<br />
انجام  میدهیم  .</p>
<p>بعد از اینکه  این  عملیات   انجام  شد، تابع  ۰۰h از INT 16h را فراخوانی  میکنیم  تا<br />
منتظر دریافت   یک   کلید از صفحه  کلید شود . به  این  ترتیب   میتوانیم  نتیجه  برنامه<br />
را مشاهده  کنیم  و کلیدی  را برای  اتمام  برنامه  بزنیم .<br />
در نهایت   باید حالت   صفحه  نمایش   را به  مود متنی  برگردانیم  .<br />
برای  اینکار از همان  تابع  تعیین  مود نمایشی  استفاده  میکنیم  و حالت   صفحه  نمایش<br />
که  با AL مشخص   میشود را برابر ۳ قرار میدهیم  .<br />
برنامه  را با روش   گفته  شده  تایپ   و کامپایل  کنید . اگر از توربو اسمبلر استفاده<br />
میکنید با فرمان  ASM/T.َTASM VGA256 آن  را به  فرم  COM. ترجمه  کنید.</p>
<div dir="ltr">
<p align="left">
<hr />.      MODEL SMALL<br />
.      CODE<br />
ORG 100H<br />
START                 :<br />
MOV AH/00H<br />
MOV AL/13H<br />
MOV BX/00H      ; PAGE NUMBER<br />
INT 10H         ; SET TO 320&#215;200 256 COLORS</p>
<p>MOV AH/0CH      ; PUTPIXEL FUNCTION<br />
MOV AL/25       ; COLOR #25<br />
MOV DX/0        ; ROW 0<br />
ROW                          :<br />
MOV CX/319      ; COLUMN 319 = START COLUMN<br />
COL         :<br />
INT 10H         ; CALL INTERRUPT 10H<br />
LOOP COL        ; DOWN TO CX=0<br />
INC DX          ; DX=DX+1<br />
INC AL          ; AL=AL+1(  COLOR NUMBER    )<br />
CMP DX/199      ; IF DX=199<br />
JNZ ROW         ; ELSE JUMP TO ROW</p>
<p>MOV AH/00H<br />
INT 16H</p>
<p>MOV AH/00H      ; VIDEO MODE SET<br />
MOV AL/03H      ; 80&#215;25 16 COLORS<br />
INT 10H         ; CALL INT .10H<br />
INT 20H         ; TERMINATE PROGRAM<br />
END START</p></div>
<p>با انجام  این  تمرین  ساده  ، یا گرفتیم  که  دانستن  یکسری  از وقفه  ها و توابع<br />
مربوط به  آنها برای  نوشتن  برنامه  های  اسمبلی  الزامی  است   .<br />
در قسمت   بعدی  نحوه  تعریف   متغیر ها ، بدست   آوردن  آدرس   آنها و چاپ<br />
پیغامها و جملات   را یاد خواهیم  گرفت   .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassemblyp108710211610-1181/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یاد بگیریم &#8211; ۹</title>
		<link>http://www.irandevelopers.com/programming/learnassemblyp98710191235-1156/</link>
		<comments>http://www.irandevelopers.com/programming/learnassemblyp98710191235-1156/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 09:05:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1156</guid>
		<description><![CDATA[دستورالعمل LOOP تا اینجا هروقت که میخواستیم یک حلقه ایجاد کنیم از دستورالعمل CMP و پرشهای شرطی استفاده میکردیم . راه ساده تری برای اجرای مکرر دستورالملها وجود دارد و آن استفاده از LOOP است . دستور LOOP به تعداد دفعاتی که با ثبات CX مشخص میکنیم حلقه ای را ایجاد میکند . برای ایجاد [...]]]></description>
			<content:encoded><![CDATA[<hr />دستورالعمل  LOOP</p>
<p>تا اینجا هروقت   که  میخواستیم  یک   حلقه  ایجاد کنیم  از دستورالعمل  CMP و پرشهای<br />
شرطی  استفاده  میکردیم  . راه  ساده  تری  برای  اجرای  مکرر دستورالملها وجود دارد و آن<br />
استفاده  از LOOP است   . دستور LOOP به  تعداد دفعاتی  که  با ثبات   CX مشخص   میکنیم<br />
حلقه  ای  را ایجاد میکند .<br />
برای  ایجاد چنین  حالتی  ابتدا مقدار لازم  را در ثبات   CX قرار میدهیم  . دستور Loop<br />
همیشه  از مقدار CX یک   واحد،یک   واحد کم  میکند تا به  ۰ برسد . وقتی  که  مقدار CX<br />
برابر ۰ شد ، از حلقه  خارج  میشود . بنا براین  برای  ایجاد حلقه  ای  که  ۱۰۰ بار<br />
تکرار شود، CX را برابر ۱۰۰ قرار میدهیم  .                                                                  MOV CX/100</p>
<p>حلقه  مورد نظر بین  دستور loop و یک   برچسب   انجام  میشود . برچسب  ، در ابتدای  حلقه<br />
و دستور loop در انتهای  آن  قرار میگیرد.</p>
<div dir="ltr">
<p align="left">
MOV CX/100<br />
LPCNT   :<br />
:<br />
:<br />
:<br />
LOOP LPCNT</p>
</div>
<p>در بالا با mov cx/100 میخواهیم  حلقه  ای  داشته  باشیم  که  ۱۰۰ بار انجام  بشود. وقتی<br />
به  loop lpcnt میرسیم ، یکواحد از مقدار CX کاسته  شده  و مجددا به  lpcnt پرش<br />
میکنیم  .<br />
به  همین  سادگی  ! .<br />
تمرین  : برنامه  ای  بنویسید که  کاراکتر های  با کد اسکی  ۳۲ تا ۲۵۵ را نمایش   دهد.</p>
<p>راهنمائی  :<br />
چون  همیشه  CX در حال  کاهش   است   ، برای  اینکه  بتوانیم  از ۳۲ تا ۲۵۵ برویم ، باید<br />
عدد داخل  CX را برابر ۳۱=۲۲۴-َ۲۵۵ قرار بدهیم  تا تعداد ۲۵۴ حرف   چاپ   بشود. سپس<br />
مقدار CX را از ۲۵۵ کم  کرده  و داخل  AL قرار میدهیم  تا با تابع  ۰Eh ار وقفه  ۱۰h<br />
چاپ   شود . این  وقفه  را در برنامه  ALLCHR.ASM توضیح  دادیم  .</p>
<p>پشته  (Stack) ، ذخیره  و بازیابی  ثباتها</p>
<p>ما تعدادی  ثبات   برای  نگهداری  و انتقال  اعداد و مقادیر داریم  ولی  کافی  نیستند .<br />
بخصوص   در DEBUG که  نمیتوانیم  متغیرتعریف   کنیم  . یا در برنامه  پیش   می  آید<br />
بخواهیم  برای  یک   کار خاص   و بطور موقت   مقدار ثبات   را تغییر دهیم  ،در این  مواقع<br />
مقدار ثبات   را در پشته  ذخیره  کرده  و بعدا مجددا بازیابی  میکنیم  .<br />
در برنامه  های  EXE. پشته  یا Stack یک   سگمنت   مستقل  است   و آدرس   آن  در ثبات   SS<br />
(Stack Segment) قرار دارد . در برنامه  های  COM. پشته  به  آنصورت   وجود ندارد و<br />
خود DOS فضای  لازم  را برای  برنامه  فراهم  میکند . در هر صورت   ما به  اینکه  پشته  در<br />
کجاست   کاری  نداریم  و به  یک   شکل  مقادیر را به  پشته  فرستاده  (PUSH) یا از آن<br />
خارج  میکنیم  (POP) .<br />
خاصیت   مهمی  که  در PUSHو POPو کردن  مقادیر به  پشته  وجود دارد اینست   که  همیشه<br />
اولین  مقداری  که  به  پشته  فرستاده  میشود، آخرین  مقداری  است   که  از پشته  خوانده<br />
میشود . مثلا فرض   کنید که  ابتدا AX و بعد CX را به  پشته  میفرستیم  . حال  برای  خارج<br />
کردن  درست   این  مقادیر، ابتدا CX و بعد AX را خارج  میکنیم  .<br />
این  قانون  اسمبلی  است   و به  (FILO=First In Last Out) معروف   است   .</p>
<p>برای  فرستادن  مقدار یک   ثبات   به  پشته  از دستور PUSH استفاده  میکنیم  .<br />
مثلا برای  قرار دادن  AX مینویسیم  : PUSH AX .                                    PUSH<br />
نمیتواند مقدار یک   نیم  ثبات   را در پشته  قرار دهد و حتما باید یک   ثبات<br />
کامل  دوبایتی  باشد .<br />
وقتی  ثباتی  را PUSH کردیم  ، مقدار آن  در Stack نگهداری  میشود و میتوانیم  مقدار آن<br />
را تغییر دهیم  .<br />
پس از آن ، از دستور POP برای خارج کردن ثبات از پشته استفاده میکنیم مانند . POP AX</p>
<p>مثال  :</p>
<div dir="ltr">
<p align="left">
۱]    MOV AX/0AH               ; ax = 0Ah<br />
2]    MOV BX/0BH               ; bx = 0Bh<br />
3]    PUSH AX                  ; push ax to stack<br />
4]    PUSH BX                  ; hold bx in stack<br />
5]    MOV AX/5                 ; now ax=5<br />
6]    MOV BX/2AH               ; and bx=2Ah<br />
7]             :               ; other commands and<br />
8]             :               ; statements  &#8230;<br />
9]    POP BX                   ; POP bx from stack<br />
10]    POP AX                   ; read ax from stack</p>
</div>
<p>در سطر ۳وَ۴ مقادیر axو bxو را به  پشته  میفرستیم  . در سطر ۵و ۶و مقادیر جدید به    ax<br />
bx/ میدهیم  و بعد از آن  یکسری  دستورات   دیگر هستند &#8230; . در سطر ۱۰ مقدار BX<br />
از داخل  Stack بیرون  کشیده  میشود . توجه  داشته  باشید که  bx را بعد از ax در پشته<br />
قرار داده  ایم  ولی  در هنگام  خارج  کردن  به  ترتیب   عکس   عمل  میکنیم  .</p>
<p>بعلاوه  دستور PUSHF به  معنی  PUSH FLAGS ، ثبات   پرچم  را در پشته  قرار میدهد . نحوه<br />
کار با آن  هم  مثل  PUSH معمولی  است   ولی  آرگومان  ندارد .<br />
مثال :                                                                                                          PUSHF</p>
<p>در قسمت   بعد، این  مطالب   را تمرین  میکنیم  و چند برنامه  نمونه  میبینیم ، حتی<br />
یک   برنامه  گرافیکی  با ۲۵۶ رنگ   مینویسیم  و در آن  از دستورات   LOOPو PUSHو<br />
استفاده  میکنیم  .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassemblyp98710191235-1156/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یاد بگیریم &#8211; ۸</title>
		<link>http://www.irandevelopers.com/programming/learnassembly8710191234-1154/</link>
		<comments>http://www.irandevelopers.com/programming/learnassembly8710191234-1154/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 09:04:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1154</guid>
		<description><![CDATA[امروز میخواهیم با مطالبی که خوانده ایم یک برنامه تمرینی بنویسیم . برنامه ای برای تعریف رنگهای جدید! اگر دارای کارت ویدئوی VGA و طبعا VGA BIOS باشید ، میتوانید از تابع ۱۰H مربوط به اینتراپت ۱۰h (که مربوط به سرویسهای تصویری است ) برای تعریف پالت های جدید استفاده کنید . تعداد رنگهائی که [...]]]></description>
			<content:encoded><![CDATA[<p>امروز میخواهیم  با مطالبی  که  خوانده ایم  یک   برنامه  تمرینی  بنویسیم  . برنامه ای<br />
برای  تعریف   رنگهای  جدید!<br />
اگر دارای  کارت   ویدئوی  VGA و طبعا VGA BIOS باشید ، میتوانید از تابع  ۱۰H مربوط<br />
به  اینتراپت  ۱۰h (که  مربوط به  سرویسهای  تصویری  است ) برای  تعریف   پالت  های  جدید<br />
استفاده  کنید . تعداد رنگهائی  که  میتوان  آنها را تغییر داد به  نوع کارت   گرافیک<br />
و VGA BIOS مربوط است  و در حالت   عادی  رنگهای  شماره  ۰تا ۷ا قابل  تعریف   هستند .<br />
پالت   رنگ   را به  این  صورت   باید تعریف   کنیم  :                                                  AH=10H<br />
AL=10H</p>
<p>شماره  رنگ   از ۰تا BX= 7ا<br />
عدد رنگ  سبز CH=<br />
عدد رنگ   آبی  CL=<br />
عددرنگ   قرمز DH=</p>
<p>رنگهائی  که  دیده  میشود ، ترکیبی  از سه  رنگ   اصلی  قرمز،سبز و آبی  (RGB) هستند .<br />
برای  تعریف   یک   رنگ   جدید نیز باید مقدار هر رنگ   اصلی  در پالت   مورد نظر را در<br />
نیم  ثباتهای  CH/CLو DHوC قرار دهیم  . این  مقادیر ۶ بیتی  و در محدوده  ۱ تا ۶۳<br />
هستند .<br />
پس   از مقداردهی  ثباتها اینتراپت   ۱۰h را فراخوانی  میکنیم  . در مثال  زیر ما رنگ<br />
شماره  ۱ که  آبی  میباشد را تغییر داده  ایم  .</p>
<p>تمرین  :   برنامه  را برای  رنگهای  شماره  ۲تا ۷ا نیز با مقادیر دلخواه  تکمیل  کنید</p>
<div dir="ltr">
<p align="left">.                MODEL SMALL<br />
.                CODE<br />
ORG 100H<br />
START       :<br />
MOV AH/010H<br />
MOV AL/010H<br />
MOV BX/1        ; COLOR NUMBER<br />
MOV CH/12       ; GREEN VALUE<br />
MOV CL/24       ; BLUE VALUE &#8211; THE 16-BIT NUMBER<br />
MOV DH/14       ; RED VALUE<br />
INT 10H         ; VIDEO BIOS INT .<br />
INT 20H         ; TERMINATE PROGRAM<br />
END START</p>
</div>
<p>ما در اینجا وجود VGA BIOS را تست   نکرده  ایم  و اگر این  برنامه  روی  کامپیوتری<br />
با کارت   گرافیک   EGA و &#8230; اجراشود نتایج  غیرقابل  پیش   بینی  بدست   خواهد آمد.<br />
یک   راه  ساده  برای  تست   وجود کارت   VGA وجود دارد . به  اینصورت   که  مقدار ثباتهای AH<br />
و ALو را به  ترتیب   برابر ۱Ah و ۰۰h قرار داده  و اینتراپت   ۱۰h را اجرا میکنیم<br />
اگر بعد از فراخوانی  وقفه  ،  AL برابر ۱Ah بود یعنی  کارت   VGA فعال  است  .<br />
پس   در برنامه ای  که  نوشتیم  میتوانیم  با یک   دستور CMP ساده  از بوجود آمدن  خطای<br />
نبود VGA BIOS جلوگیری  کنیم  .<br />
بنا براین  برنامه  را به  این  صورت   تکمیل  میکنیم  :</p>
<div dir="ltr">
<p align="left">.          MODEL SMALL<br />
.          CODE<br />
ORG 100H        ; BEGINING OFFSET : 100H<br />
START    :</p>
</div>
<div dir="ltr">
<p align="left">MOV AH/1AH<br />
این  قسمت   را  |                                  MOV AL/00<br />
اضافه کرده ایم | INT 10H CMP AL/1AH ; VGA BIOS EXIST? |</p>
<p>; NO  UJUMP TO THE END       JNZ NOVGA<br />
MOV AH/010H<br />
MOV AL/010H<br />
MOV BX/1        ; COLOR NUMBER<br />
MOV CH/12       ; GREEN VALUE<br />
MOV CL/24       ; BLUE VALUE &#8211; THE 16-BIT NUMBER<br />
MOV DH/14       ; RED VALUE<br />
INT 10H         ; VIDEO BIOS INT.<br />
NOVGA:<br />
INT 20H         ; TERMINATE PROGRAM<br />
END START</p>
</div>
<p>در برنامه  بالا اگر بعد از اجرای  وقفه  ۱۰h مقدار AL برابر ۱Ah نباشد، نمیتوانیم<br />
از سرویس  تعریف  رنگ   استفاده  کرده  و مجبوریم  برنامه  را با پرش   به  NOVGA خاتمه<br />
دهیم  .</p>
<p>در این  قسمت  با نوشتن  یک  برنامه ، دو تابع  مفید از وقفه  ۱۰h را یاد گرفتیم  و<br />
دیدیم  که  نوشتن  یک  برنامه  اسمبلی  برخلاف   آنچه  تا بحال  تصور میکردیم  چقدر ساده<br />
و جالب   است   .<br />
پیروز باشید</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassembly8710191234-1154/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>اسمبلی یاد بگیریم &#8211; ۷</title>
		<link>http://www.irandevelopers.com/programming/learnassemblyp78710191233-1152/</link>
		<comments>http://www.irandevelopers.com/programming/learnassemblyp78710191233-1152/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 09:03:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[اسمبلی - Assembly]]></category>
		<category><![CDATA[برنامه نویسی]]></category>

		<guid isPermaLink="false">http://www.irandevelopers.com/?p=1152</guid>
		<description><![CDATA[پرشهای غیر شرطی ے اگر با زبانهائی مثل Basicیا Pascalا برنامه نویسی کرده باشید حتما از دستور Goto ے هم استفاده کرده اید . بوسیله این فرمان ، ما میتوانستیم روال اجرای برنامه را به یک نقطه مشخص انتقال بدهیم بدون اینکه نیاز به برقراری شرط خاصی باشد . در زبان اسمبلی هم چنین دستوری [...]]]></description>
			<content:encoded><![CDATA[<p>پرشهای غیر شرطی</p>
<p>ے  اگر با زبانهائی  مثل  Basicیا Pascalا برنامه  نویسی  کرده  باشید حتما از دستور Goto<br />
ے  هم  استفاده  کرده  اید . بوسیله  این  فرمان ، ما میتوانستیم  روال  اجرای  برنامه  را به<br />
یک   نقطه  مشخص   انتقال  بدهیم  بدون  اینکه  نیاز به  برقراری  شرط خاصی  باشد .<br />
در زبان  اسمبلی  هم  چنین  دستوری  داریم  : دستورالعمل  JMP (مخفف  JUMP) .<br />
دستور JMP به  این  شکل  استفاده  میشود:<br />
برچسب  JMP<br />
ے  منظور از برچسب   مکانی  از برنامه  است   . در اسمبلی  برای  اینکه  یک  نقطه  از برنامه<br />
ے  را علامت   بزنیم  ، نام  برچسب   مورد نظر را مینویسیم  و برای  اینکه  اسمبلر آن  را با<br />
ے  یک   دستورالعمل  اجرائی  اشتباه  نکند، کاراکتر (:) را در مقابل  آن  قرار میدهیم<br />
مانند:                                       :Start<br />
سپس میتوانیم با دستور JMP به آنحا پرش کنیم : Start :<br />
:<br />
:<br />
Jmp Start</p>
<p>دقت   کنید که  بعد از Start ی  که  در مقابل  JMP نوشتیم  علامت   : قرار نداده  ایم  .<br />
ے  این  JMP ها از نوع JUMP NERA هستند و نوعی  دیگر بنام  JUMP FAR هم  داریم  که  بزودی<br />
آن  را هم  یاد میگیریم  .<br />
ے  مثال  :  برنامه  ای  که  در مثالهای  قبل  نوشتیم  را در نظر بگیرید . اگر ما از روی<br />
دستورالعملهای برنامه با JMP پرشی انجام دهیم هیچکدام از آن کدها اجرا نخواهندشد:</p>
<div dir="ltr">
<p align="left">۱]       JMP Quit                                  _<br />
2]           mov ax/0E07h<br />
3]           int 10h<br />
4]       Quit                                     :_<br />
5]           int 20h</p>
</div>
<p>برنامه از روی سطرهای ۲وَ۳ پرش خواهد کرد .</p>
<p>ثبات   پرچم  (Flags)</p>
<p>ے  ثبات   پرچم  یک   ثبات   ۱۶ بیتی  است   که  ۱یا ۰ا بودن  بیتهای  آن  نشانه  درست   یا<br />
ے  نادرست   بودن  یک   شرط است   . مثلا اگر با دستورالعمل  خاصی  (میخوانیم  ) تست   کنیم<br />
که  آیا ثبات   BX مقدار ۰ را دارد ، در این  صورت   بیت   ۶ برابر ۰ میشود و &#8230; .<br />
از این ۱۶ بیت فقط ۹ بیت استفاده میشود که به شرح زیر هستند :<br />
۱۶ ۱۵ ۱۴ ۱۳ ۱۲ ۱۱ ۱۰ ۹ ۸ ۷ ۶ ۵ ۴ ۳ ۲ ۱ ۰<br />
*  *  *  *  *  O  D  I T S Z * A * P * C</p>
<p>علامت * به معنای بی استفاده بودن است .</p>
<p>ے  ۱- پرچم  نقلی  یا (CF) . بیت   ۰ در نتیجه  اجرای  وقفه  ها یا بعضی  اعمال  حسابی  تغییر<br />
میکند .<br />
ے  ۲-پرچم  توازن  (ZF) . بر اساس   یک   عمل  مقایسه  ای  یا حسابی  تغییر میکند . اگر<br />
نتیجه  یک   عبارت   ۰ باشد مقدار ۱ و اگر نتیجه  ۱ باشد مقدار ۰ میگیرد.<br />
ے  ۳-پرچم  وقفه  (IF) . اگر ۰ باشد هیچ  وقفه  ای  نمیتواند اجرا شود و اگر ۱ باشد<br />
میتوان وقفه ها را فراخوانی کرد .</p>
<p>ے    و &#8230; . ۶ پرچم  دیگر را فعلا لازم  نداریم  بنا براین  توضیحی  برای  آنها ارائه<br />
نمیکنیم .</p>
<p>دستور مقایسه  ای  CMP</p>
<p>ے    برای  مقایسه  مقادیراز دستور CMP (مخفف   CoMPare) استفاده  میکینم  . این  دستور<br />
ے    مقدار داخل  یک   ثبات   یا متغیر را با مقداری  دیگر مقایسه  کره  و روی  ثبات   های<br />
ے    CFو ZFو تاثیر میگذارد . بعد از مقایسه  میتوانیم  بر حسب   وضعیت   پرچمها پرش<br />
لازم را انجام دهیم .</p>
<p>ے  مثلا CMP BX/0 تست   میکند که  آیا مقدار BX برابر ۰ است   یا نه  . در صورتی  که  برابر<br />
۰<br />
باشد ،پرچم  ZF برابر ۱ میشود .<br />
با همین دستور CMP میتوانیم کوچکتر،بزرگتر و &#8230;. را هم تست کنیم .</p>
<p>پرشهای  شرطی</p>
<p>برای  پرشهای  شرطی  از دستورهای  زیر درست   مثل  JMP استفاده  میکنیم  .<br />
ے  JE/JZ : اگر محتوای  ZF صفر باشد جهش  میکند . اگر دو مقداری  که  مقایسه  کرده  ایم<br />
برابر باشیند پرش   انجام  میشود.<br />
ے  JNE/JNZ : برعکس   JZو JEو هستند و اگر ZF یک   باشد (بعبارتی  دو مقداری  که  مقایسه<br />
کردیم  برابر نباشند) جهش   انجام  میشود.<br />
ے  JA/JNBE . اگر محتوای  ثبات   یا متغیری  که  مقایسه  کرده  ایم  بزرگتر از عدد مورد نظر<br />
باشد پرش انجام میدهد . مثلا :</p>
<div dir="ltr">
<p align="left">mov bh/1<br />
cmp bh/10<br />
ja  Dest</p>
</div>
<p>ے  مقدار BH برابر ۱ است   و در سطر دوم  تست   آن  را با ۱۰ مقایسه  میکنیم  . در سطر سوم<br />
چون BH بزرگتر از ۱ نیست ، پس پرش JA Dest انجام نمیشود .</p>
<p>JAE/JNB . اگر بزرگتر یا مساوی  باشد ، پرش   انجام  میشود.<br />
JB/JNAE: در صورتی  که  کوچکتر باشد پرش   انجام  میشود.<br />
JBE : در صورتی که کوچکتر یا مساوی باشد پرش انجام میشود .</p>
<p>مثال  :<br />
ے              میخواهیم  برنامه  ای  بنویسیم  که  تمام  کاراکترهای  بین  ۱۲۸ تا ۲۵۵ را<br />
چاپ کند.</p>
<div dir="ltr">
<p align="left">.          MODEL SMALL<br />
.          CODE<br />
ORG 100H<br />
START                                                                :</p>
<p>کاراکتر ۱۲۸ برای شروع ; MOV CH/128 CHARS :</p>
<p>کداسکی  را درAL قرار میدهیم  تا چاپ   شود ;      MOV AL/CH<br />
سرویس    ۰Eh برای  چاپ   کاراکتر         ;    MOV AH/0EH<br />
اینتراپت    ۱۰h                         ;        INT 10H<br />
یکواحد به   CH  اضافه  کن               ;         INC CH<br />
مقایسه   CH با ۲۵۵                      ;     CMP CH/255<br />
اگر مساوی  نباشد به   CHARS پرش   میکند   ;      JNZ CHARS<br />
پایان ; INT 20H END START</p>
</div>
<p>ے  تمام  برنامه  ساده  و روشن  است   ولی  در سطر آخر نکته  جدیدی  وجود دارد . بعد از<br />
ے  END نام  برچسب   Start را آورده  ایم  . نکته  ای  که  در نوشتن  برنامه  های  اسمبلی  باید<br />
ے  مراعات   کنیم  اینست   که  : اگر از برچسبی  در برنامه  استفاده  میکنیم  ، اسمبلر باید<br />
ے  یک   برچسب   را به  عنوان  نقطه  آغاز کدبرنامه  ببیند . به  همین  خاطر علاوه  بر برچسب<br />
ے  CHARS یک   برچسب   بنام  Start هم  در ابتدای  برنامه  تعریف   کرده  و برای  اینکه<br />
ے  اسمبلر بداند مما کدام  برچسب   را برای  انیکار اینخاب   کرده  ایم  ، نام  آن  را در<br />
مقابل END می آوریم ، یعنی END START .</p>
<p>ے  نکته  دیگر اینکه  ، در اسمبلر هر چیزی  که  بعد از کاراکتر (;) باشد ، توضیح<br />
ے  (Comment) فرض   شده  و اصلا ترجمه  نمیشود . (مثل  REM در بیسیک  و .. ) . هر comment<br />
ے  باید در یک   سطر جای  داده  شود و اگر از این  مقدار بیشتر بود میتوانیم  در سطر بعد<br />
هم یک کاراکتر (;) درج کرده و ادامه توضیحات را بعد از آن بیاوریم .</p>
<p>پایان یخش هفتم</p>
]]></content:encoded>
			<wfw:commentRss>http://www.irandevelopers.com/programming/learnassemblyp78710191233-1152/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

