تبلیغات :
آکوستیک ، فوم شانه تخم مرغی، صداگیر ماینر ، یونولیت
دستگاه جوجه کشی حرفه ای
فروش آنلاین لباس کودک
خرید فالوور ایرانی
خرید فالوور اینستاگرام
خرید ممبر تلگرام

[ + افزودن آگهی متنی جدید ]




صفحه 3 از 4 اولاول 1234 آخرآخر
نمايش نتايج 21 به 30 از 38

نام تاپيک: آموزش کامل عالی اسمبلی

  1. #21
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    بافر صفحه كليد و بافرحلقوي

    صفحه كليد از طريف وقفه سخت افزاري 9h كنترل ميشود . وقتي كه كليدي فشرده شده يا
    رها شود اين وقفه فراخواني خواهد شد.
    صفحه كليد هم مانند بسياري از وسايل جانبي مثل ديسك درايو و ... از طريق پورت
    مخصوص به خودش با CPU مرتبط ميشود. وقتي كه كليدي فشرده ميشود پردازنده مخصوص
    صفحه كليد كه يك تراشه 8048 است كدي موسوم به كد اسكن توليد كرده و در پورت 60h
    قرار ميدهد. پس از آن وقفه 9h اين مقدار را از پورت 60h خوانده و در بافر صفحه
    كليد قرار ميدهد . با فرصفحه كليد در ناحيه داده هاي بايوس يعني سگمنت شماره 40h
    قرار دارد.

    بافر حلقوي ----------

    بافر صفحه كليد يك ناحيه 16 كلمه اي (32 بايتي ) در ناحيه داده هاي
    كاراكتر بعدي از آنجا خوانده خواهد شد . كلمه ديگري بنام Tile هم به موقعيتي
    اشاره ميكند كه كاراكتر بعدي كه تايپ ميشود در آن محل قرار ميگيرد.
    وقتي يك كاراكتر تايپ ميشود head حركت ميكند و وقتي يك كاراكتر وارد ميشود Tile
    يك خانه به جلو ميرود و وقتي هركدام به انتها رسيد به جاي اولش برميگردد. به
    شكلي كه هميشه head در تعقيب tile است و وقتي بافر خالي باشد به آندو برهم منطبق
    ميشوند . به خاطر اين شكل عملكرد بافر به آن بافرخلقوي ميگوئيم .

    دستيابي به ناحيه داده ها و بافر صفحه كليد -----------------------------------------

    براي دستيابي به يك سگمنت بايد دو موضوع جديد را ياد بگيريم . يكي تعريف يك
    ناحيه بعنوان يك سگمنت و ديگري منطبق كردن يك ناحيه تعريف شده بر يك سگمنت حافظه
    براي تعريف يك سگمنت از كلمه Segment استفاده ميكنيم . توجه داريم كه اين تعريف
    حتما بايد قبل از code. باشد.

    Bios_Data SEGMENT
    :
    :
    Bios_Data Ends


    به اين ترتيب يك ناحيه داده اي جديد به اسم Bios_data تعريف كرديم .
    براي اينكه اين ناحيه را بر سگمنت 40h يا همان ناحيه داده هاي بايوس منطبق كنيم
    راهنماي AT را هم به انتهاي تعريف سگمنت اضافه ميكنيم . Bios_Data SEGMENT AT 40H
    :
    Bios_Data Ends

    حالا در داخل سگمنت تعريفي چند متغير را در آدرسهاي مخصوص تعريف ميكنيم . چون
    بايتهاي مربوط به صفحه كليد در آفست 1Ah قرار دارند يك org 1Ah در نظر گرفته و
    متغيرها را تعريف ميكنيم .

    Bios_Data SEGMENT AT 40H
    ORG 100H
    HEAD DW ?
    TAIL DW ?
    BUFFER DW 10 DUP(?)
    Bios_Data Ends
    org 1ah

    به اسمبلر ميگويد كه همه متغيرهائي كه در زير تعريف ميشوند را منطبق
    بر آدرس 1ah قرار بدهد . اين كار باعث ميشود كه هميشه متغير head حاوي دوبايت 1ah
    و 1bhو باشد.
    ون هميشه مقدار آدرسها نسبت به محتواي DS سنجيده ميشوند ( مثلا mov al/[bx] با mov al/ds:[bx]
    برابر است ) بايد به اسمبلر بگوئيم كه داده ها در كجا هستند.
    براي اين منظور از ASSUME استفاده ميكنيم . به اين صورت


    Bios_Data SEGMENT AT 40H
    ORG 100H
    HEAD DW ?
    BUFFER DW 10 DUP(?)
    Bios_Data Ends
    . CODE
    ORG 100H
    START:
    ASSUME DS:BIOS_DATA


    بعد آدرس ناحيه Bios_data را به DS لود ميكنيم . ( با استفاده از رجيستر واسطه ) MOV BX/BIOS_DATA
    MOV DS/BX

    حال تست ميكنيم كه اگر headو tail برهم منطبق باشند يعني بافر خالي است و
    شروع به خواندن كليد ها ميكنيم اما اگر برهم منطبق نباشند محتواي بافر را خوانده
    و آن را خالي ميكنيم .

    GETCHAR:
    MOV BX/HEAD
    CMP BX/TAIL
    JE GETCHAR



    واگر بافر خالي نبود BX محل آخرين كاراكتر داخل بافر را نشان ميدهد . پس محتواي
    آن قسمت را خوانده و سپس Tail را هم به همان آدرس تنظيم ميكنيم كه Tailو Headو
    بر هم منطبق شوند . ( يعني بافر خالي بشود) MOV DX/[BX]

    و ميتوانيم تست كنيم كه اگر كليد خوانده شده Q ( به معني Quit) بود از برنامه
    خارج شويم و در غير اينصورت يك كليد ديگر را بخوانيم و در صفحه چاپ كنيم .

    آيا كاراكتر Q است ? ; CMP DDL/'Q' JE BYE ;

    آيا كاراكتر q است ? ; CMP DL/'q' JE BYE ;

    تابع 2 براي خواندن كليد ; .MOV AH/2 ; READ A CHAR
    وقفه داس ; INT 21H
    پرش به روتين برنامه ; JMP GETCHAR BYE :INT 20H

  2. #22
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    برنامه نويسي صفحه تصوير
    ے بايوس كامپيوتر هاي PC شامل روالهائي براي كنترل و برنامه نويسي صفحه نمايش
    هستند. متداولترين آنها وقفه 10h است و در زير متداولترين توابع آن را شرح ميدهيم

    سرويس 2 براي تنظيم محل مكان نما
    ورودي ها: AH=2

    سطر و ستون موقعيت جديد DH/DL=
    شماره صفحه BH=
    ے شماره صفحه در حالت پيش فرض 0 است (BH=0) و گوشه بالا و سمت چپ صفحه نمايش
    ے هم با مختصات (0/0) سنجيده ميشود . بنا براين درحالت 80x25 حداكثر شماره سطر و
    ستون برابر 79x24 است .

    سرويس 3 . دريافت موقعيت مكان نما
    ورودي ها AH=3

    شماره صفحه BH=
    بعد از فراخواني وقفه 10h اين مقادير برگشت داده ميشوند:
    سطر و ستون فعلي مكان نما DH/DL=

    مثال

    MOV AH/2 ; Set curson position .
    MOV DH/20 ; X
    MOV DL/10 ; Y
    XOR BH/BH ; BH=0
    INT 10H ; Call Interrupt 10h




    لغزاندن صفحه به بالا يا پائين
    ے با استفاده از دو تابع زير ميتوانيم بخشي از صفحه تصوير را به بالا يا پائين حركت
    داده يا آن قسمت را پاك كنيم .
    براي فراخواني اين توابع بايد رجيسترها را بصورت زير تنظيم كنيم
    لغزش بطرف بالا AH=6
    لغزش بطرف پائين AH=7
    تعداد سطرهائي كه بايد حركت كند AL=
    سطروستون گوشه سمت چپ و بالا Ch/Cl=
    سطرو ستون گوشه سمت راست و پائين Dh/Dl=
    مشخصه رنگ Bh=

    ے اگر AH برابر 6 باشد محدوده تعريفي بطرف بالا و در صورتي كه 7 باشد بطرف پائين
    حركت داده ميشود .
    AL مشخص ميكند كه محدوده مورد نظر چند سطر بايد حركت كند .
    ے اگر AL برابر 0 باشد محدوده تعريفي پاك ميشود . مثلا فرمان CLSدر DOSر از همين
    وقفه استفاده كرده و كل صفحه نمايش را پاك ميكند.
    ے مشخصه رنگي كه با BH تعريف ميشود معلوم ميكند كه فضاي خالي كه بعد از حركت دادن
    محدوده بوجود مي آيد بايد با چه رنگي پر شود. اين مقدار از رابطه زير بدست
    مي آيد:
    رنگ زمينه +16*رنگ متن BH=
    مثلا براي اينكه رنگ سفيد روي آبي داشته باشيم : BH=15+1*16=31

    نوشتن كاراكتر و خصوصيات در محل مكان نما
    ے با استفاده از تابع شماره 9h ميتوانيم كاراكتري را با خصوصيات مورد نظر در محل
    مكان نما چاپ كنيم .
    AH=9

    كد اسكي AL=
    شماره صفحه BH=
    خصوصيات كاراكترBL=
    تعداد دفعاتي كه كاراكتر چاپ ميشودCX=

    ے خصوصيات كاراكتر از روشي كه در بالا توضيح داديم بدست مي آيد. رجيستر CX معلوم
    ے ميكند كه كاراكتر مشخص شده با AL چند بار بايد چاپ شود. معمولا اين مقدار را 1
    قرار ميدهيم .
    مثال : چاپ رشته كاراكتري بصورت سفيد روي آبي

    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    JMP MAIN
    MSG DB ' THIS IS AN EXAMPLE FOR INT 10H/FUNCTION 9H$'

    SETCURSOR PROC ; SET CURSOR POSITION
    MOV AH/2 ; FUNCTION 2 / INT 10H
    MOV DH/10 ; ROW:10
    PUSH BX ; SAVE BX VALUE
    MOV BH/0
    INT 10H
    POP BX
    RET
    SETCURSOR ENDP

    WRITE PROC ;WRITE A CHARACTER USING FUNCTION 9H/INT 10H
    MOV AH/09
    PUSH BX
    XOR BH/BH
    MOV BL/31
    MOV CX/1
    INT 10H
    POP BX
    RET
    WRITE ENDP

    MAIN:
    LEA BX/MSG ; GET MSG ADDRESS
    MOV DL/10 ; COLUMN : 10
    CALL SETCURSOR
    LOOP:_
    MOV AL/[BX]
    CMP AL/'$'
    JZ QUIT
    CALL WRITE
    INC BX
    INC DL ; SET NEW CURSOR LOCATION
    CALL SETCURSOR
    JMP LOOP_
    QUIT:
    INT 20H ; TERMINATE
    END START





    سرويس 0Eh براي چاپ بصورت تله تايپ

    ے وقتي ميخواهيم با استفاده از سرويس 9h كاراكتري را چاپ كنيم خودمان بايد محل
    ے مكان نما را معين كنيم . مثلا براي چاپ يك رشته كاراكتري بعد از چاپ هر كاراكتر
    يكواحد به شماره ستون مكان نما اضافه كرده ، محل جديد آن را تنظيم مكنيم و... .
    اما سرويس 0E بعد از چاپ هر كاراكتر مكان نما را يكخانه با راست انتقال ميدهد
    به خاطر همين خصوصيت به اين روش چاپ " تله تايپ " ميگويند.
    ے قبلا با اين سرويس كار كرده ايم بنا براين تنها به ياد آوري پارامترهاي لازم اكتفا
    كرده و از آوردن مثال خودداري ميكنيم . ( مثال : فايل ALLCHAR.ASM)

    بايد تنظيم شود: AH=0Eh

    كد اسكي كاراكترAL=
    شماره صفحه BH =

  3. #23
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    برنامه نويسي در مد گرافيك

    ے تنها امكاني كه بايوس براي انجام كارهاي گرافيكي در اختيار ما قرار ميدهد روشن
    ے كردن يك نقطه (Pixel) است . با استفاده از تابع مربوطه بايد زيربرنامه هائي
    براي رسم ساير اشكال گرافيكي مثل مربع ، دايره و ... بنويسيم .

    ے قبل از اينكه يك شكل گرافيكي رسم كنيم ، بايد ايتدا صفحه نمايش را در مد
    ے گرافيكي قرار بدهيم . به عبارت ديگر چون در حالت عادي تعداد سطر و ستونهاي صفحه
    ے تصوير كم ( مثلا در مد 25x80 برابر 2000 تا) است ، نميتوان شكل گرافيكي رسم كرد .
    بهمين دليل صفحه نمايش را در مد گرافيكي مثلا 480x640 نقطه قرار ميدهيم و ... .

    سرويس 0 از وقفه 10h براي تنظيم حالت صفحه نمايش =================================================

    ے براي تنظيم حالت صفحه نمايش به يك حالت متني يا گرافيكي خاص بايد اين
    پارامتر ها را تنظيم كنيم . AH=0

    مود مورد نظر AL=

    مود مورد نظر از جدولي بدست مي آيد كه خلاصه آن را در زير مي آوريم .

    كد | وضوح | تعداد رنگ
    16 | Text Mode | 03h
    16 | 320x200 | 0Dh
    16 | 640x200 | 0Eh
    Mono | 640x350 | 0Fh
    16 | 640x350 | 10h
    2 | 640x480 | 11h
    16 | 640x480 | 12h
    256 | 320x200 | 13h



    سرويس 0Ch از وقفه 10h براي نوشتن نقطه گرافيكي =============================================

    براي روشن كردن يك پيكسل از تابع 0Ch استفاده ميكنيم .
    AH= 0Ch

    شماره رديف بسته به مود تصويري DX=
    شماره ستون بسته به مد تصويري CX=
    عدد رنگ بسته به مد تصويري AL=
    شماره صفحه ، شماره 0 معمولا استفاده ميشودBh=

    ے به عنوان مثال براي روشن كردن نقطه اي كه ( مد 640x480 ) در وسط صفحه است به
    اينصورت بايد وقفه را فراخواني كنيم .

    MOV AH/0CH
    MOV DX/240
    MOV CX/320
    XOR BH/BH



    ے مثال : برنامه زير200 رنگ از رنگهاي موجود در حالت 320x200 نقطه و 256 رنگ را
    نمايش ميدهد.

    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    MOV AH/00H
    MOV AL/13H
    MOV BX/00H ; PAGE NUMBER
    INT 10H ; SET TO 320x200 256 COLORS

    MOV AH/0CH ; PUTPIXEL FUNCTION
    MOV AL/25 ; COLOR #25
    MOV DX/0 ; ROW 0
    ROW:
    MOV CX/319 ; COLUMN 319 = START COLUMN
    COL:
    INT 10H ; CALL INTERRUPT 10H
    LOOP COL ; DOWN TO CX=0
    INC DX ; DX=DX+1
    INC AL ; AL=AL+1( COLOR NUMBER)
    CMP DX/199 ; IF DX=199
    JNZ ROW ; ELSE JUMP TO ROW

    MOV AH/00H ; GET KEY
    INT 16H

    MOV AH/00H ; VIDEO MODE SET
    MOV AL/03H ; 80x25 16 COLORS
    INT 10H ; CALL INT .10H

    INT 20H ; TERMINATE PROGRAM
    END START




    سرويس 10h از اينتراپت 10h براي تنظيم پالت رنگ ================================================

    ے با استفاده از اين سرويس ميتوانيم رنگهاي فعلي سيستم را بصورت دلخواه خودمان
    ے تعريف كنيم . در هر كارت گرافيكي مبتني بر VGA ثباتي بنام رجيستر DAC وجود
    دارد كه مشخصات رنگ را بصورت زير نگهداري ميكند.
    6 bytes

    DAC Register : RRRRRRGGGGGGBBBBBB

    6 bytes 6 bytes


    ے هر رنگ از سه رنگ اصلي قرمز (R) ، سبز (G) و آبي (B) تشكيل ميشود . ثبات DAC
    ے كه بصورت يك متغير 18 بيتي است ، مقدار هر كدام از رنگهاي اصلي كه در رنگ
    ے مورد نظر شركت دارند را معين ميكند . هر كدام از اين مقدار ها يك داده 6 بيتي
    ے هستند ، بنا براين عددي بين 0 تا 63 را نشان ميدهند . براي تنظيم اين رجيستر از
    سرويس 10 استفاده ميكنيم .
    AH= 10H
    AL= 10H

    كد مربوط به رنگ (0-255) BX=
    شدت رنگ سبز CH=
    شدت رنگ آبي CL=
    شدت رنگ قرمز CH=

    ے منظور از شدت رنگ ، همان عدد 6 بيتي است كه در بالا گفتيم . مثلا اگر بخواهيم كه
    ے رنگ شماره 1 كه در حالت عادي آبي است را به قرمز تند تبديل كنيم از اين كد
    استفاده ميكنيم .


    MOV AX/1010H
    MOV BX/1
    MOV CH/1
    MOV CL/1
    MOV CH/60
    INT 10H




    پايان قسمت بيست ودوم

  4. #24
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    دسترسي مستقيم به حافظه ويدئو

    ے در اين قسمت ميبينيم كه چطور در اسمبلي بدون استفاده از وقفه ، كاراكترها را در
    صفحه نمايش چاپ كنيم . به همين صورت نوشتن نقاط گرافيكي را انجام ميدهيم و ..

    ے كارت هاي گرافيكي مبتني بر CGA/EGA/VGA داراي قطعه حافظه ي مخصوصي هستند كه
    ے اطلاعات صفحه نمايش در آن نگهداري ميشود . به عبارت ديگر هر چيزي در اين قسمت
    از حافظه نوشته شود ، روي صفحه نمايش ائير صفحه نمايش ميگذارد .
    ے در حالت گرافيكي اين قطعه از آدرس A000h و در مود متني از B000h يا B8000h شروع
    ے ميشود . در حالت متني قطعه ويدئو در هر سگمنتي كه باشد ، هميشه بايتهاي زوج ( با
    ے شروع از صفر) مربوط به كد اسكي كاراكتر بوده و بايتهاي فرد ( با شروع از يك )
    ے مربوط به خصلت كاراكتر است . يعني خصلت كاراكتري كه در آفست n ام قرار دارد
    در آفست n+1 ام قرار ميگيرد و ... .
    خصلت مربوط به هر كاراكتر از فرمول زير محاسبه ميشود :
    رنگ زمينه +16*رنگ متن = خصلت

    بعنوان مثال اگر بخواهيم كه كاراكتر چاپ شونده با رنگ سفيد روي زمينه آبي ديده
    شود داريم : = 31 َ= 15+1*16 خصلت .

    ( كد اسكي كاركتر) آفست 0
    ( بايت خصيصه ) آفست 1 | | |
    | |
    0 1 2 3 4 5 ......................................





    | | | | | | | |


    ے در كارتهاي گرافيكي تك رنگ (Monochrome) مانند CGA/MDA و ... قطعه حافظه ويدئو (
    براي مود متني ) از آدرس B000h و در كارتهاي رنگي از آدرس B800h شروع ميشود .
    ے مثال : برنامه زير تمام صفحه نمايش را با كاراكتر (.) و به رنگ سفيد روي زمينه
    آبي پر ميكند.



    مشخصه كاراكترها ; EQU 31 ATTR E
    آدرس قطعه ويدئو ; VIDSEG EEQU 0B800H . MODEL SMALL
    . CODE
    ORG 100H
    START :
    JMP MAIN
    DPRINT PROC
    PUSH ES
    MOV AX/VIDSEG
    MOV ES/AX ;

    كاراكتر براي چاپ MOV AL/'.' ; MOV ES:[BX]/AL ;

    آفست قرار گيري بايت خصيصه INC BX ; MOV AL/ATTR
    MOV ES:[BX]/AL
    POP ES
    RET
    DPRINT ENDP

    MAIN :

    آفست شروع = صفر ; XOR BX/BX LOOP :_
    CALL DPRINT

    كاراكتر بعدي ; INC BX CMP BX/4000 ;( 80X25)x2
    JNZ LOOP _
    INT 20H
    END START



    ے در برنامه بالا محل آفست ها با BX مشخص ميشود . بنابراين ابتدا كد اسكي كاراكتر
    را در آدرس ES:[BX] نوشته و سپس بايت مشخصه را در ES:[BX+1] قرار ميدهيم و..
    ے چون صفحه نمايش داراي 80x25 عنصر بوده و هر كاراكتر 2 بايت ( كد كاراكتر و
    ے بايت مشخصه ) اشغال ميكند بنا براين 80x25x2=4000 بايت طول دارد . بنا براين در
    پايان برنامه تست ميكنيم كه آيا BX با آفست 4000 ام رسيده يا نه .

    تمرين : برنامه اي بنويسيد و در آن پروسيجري طراحي كنيد كه يك رشته كاراكتري
    را با اين روش بنويسد.

    ے با همين روش ميتوانيم قسمتي از صفحه نمايش را ذخيره و بازيابي كنيم . برنامه
    ے هائي كه در آنها از منوها و پنجره ها استفاده شده همگي از اين روشها استفاده
    ے ميكنند . به اينصورت كه قبل از نمايش يك پنجره ( مثل يك Dialog box) ابتدا
    محتواي پشت آن را ذخيره كرده و بعدا دوباره در همان محل قرار ميدهند.
    برنامه زير ابتدا كل صفحه نمايش را در بافري ذخيره كرده و مجددا نمايش ميدهد

    VIDSEG EQU 0B800h
    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    JMP MAIN
    BUF DB 4000 DUP(0)
    MSG DB ' NOW PRESS ANY KEY TO RESTORE SCREEN IMAGE$'
    MAIN:
    XOR BX/BX
    PUSH ES
    MOV AX/VIDSEG
    MOV ES/AX
    LOOP1:
    MOV AL/ BYTE PTR ES:[BX]
    MOV BUF[BX]/AL
    INC BX
    CMP BX/4000
    JNZ LOOP1

    ; Clera screen.
    MOV AL/0
    MOV DH/24
    MOV DL/79
    XOR CX/CX
    XOR BH/BH
    MOV AH/7
    INT 10H

    ; DISPLAY MESSAGE
    MOV AH/9
    LEA DX/MSG
    INT 21H

    ; Wait for a key
    MOV AH/0
    INT 16H

    XOR BX/BX
    LOOP2:
    MOV AL/BUF[BX]
    MOV BYTE PTR ES:[BX]/AL
    INC BX
    CMP BX/4000
    JNZ

  5. #25
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    دستورات مربوط به رشته ها

    قبلا تا حدودي نحوه كار با كاراكتر ها و رشته هاي كاراكتري را ديديم و ميتوانيم
    آنها را از طريق ورودي دريافت كرده يا روي صفحه نمايش چاپ كنيم .
    بعلاوه عمليات فوق ، امكانات و دستورات ديگري هم در نظر گرفته شده اند . مثلا
    پردازنده 8086 دو رجيستر SI/DI را براي پردازش رشته هاي كاراكتري در نظر گرفته .
    اين دو براي انتقال داده ها بين دو آدرس مختلف يا انتقال محتواي يك رشته
    كاراكتري به رشته كاراكتري ديگر بكار ميروند.
    هميشه DS:SI(SI( مخفف Source Index است ) به رشته مبدا و ESI(Destination Index)
    به رشته مقصد (يا آدرس مقصد) اشاره ميكند. وقتي كه يك بايت (يا كلمه ) بوسيله
    دستورات مخصوص اينكار انتقال پيدا كرد، خود بخود SI يكواحد افزايش (يا كاهش )
    پيدا ميكند.
    *
    دستور MOVSB

    دستور MOVSB يك بايت را از آدرس DS:SI به آدرس ESI منتقل ميكند.
    براي انتقال يكبايت ، ابتدا ثباتهاي DS:SI را به رشته مبدا و ESI را به رشته
    مقصد تنظيم كرده و با تشكيل يك حلقه (Loop) به تعداد مورد نياز داده انتقال
    ميدهيم .
    در مثال زير ميخواهيم تمام محتواي رشته كاراكتري S1 را به رشته كاراكتري S2
    انتقال داده و S2 را چاپ كنيم .
    بنا براين دو رشته كاراكتري (با طول 20 حرف ) تعريف ميكنيم .


    S1 DB ' THE SOURCE STRING $'
    S2 DB ' $'



    سپس ds:di را به طوري تنظيم ميكنيم كه به S1 اشاره كند. چون برنامه ما com. است
    و محتواي ds ثابت ، فقط مقدار آفست s1 را به SI انتقال ميدهيم : lea ax/s1
    mov ds/ax

    براي تنظيم كردن آدرس مقصد، مقدار DS كه حاوي عدد قطعه S2 است را به ES انتقال
    ميدهيم : mov ax/ds
    mov es/ax

    سپس مقدار آفست S2 را بدست آورده و در DI قرار ميدهيم : lea ax/s2
    mov di/ax

    الان آدرسهاي مبدا و مقصد معلوم شده اند، بنا براين كافيست 20 بار (براي انتقال 20
    بايت ) ، دستور movsb را اجرا كنيم : mov cx/20 ; loop counter
    loop :_
    movsb
    loop loop _


    سپس با استفاده از تابه 9h از وقفه 21h محتواي S2 را چاپ ميكنيم و خواهيم ديد
    كه عبارت داخل S1 چاپ ميشود .



    ليست كامل : .286c
    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    JMP MAIN
    S1 DB 'THE SOURCE STRING $'
    S2 DB ' $'
    MAIN:
    LEA AX/S1
    MOV SI/AX

    LEA AX/S2
    MOV DI/AX
    ;PUSH ES
    MOV AX/DS
    MOV ES/AX

    MOV CX/20
    CLD
    LOOP:_
    MOVSB
    LOOP LOOP_
    MOV AH/09
    LEA DX/S1
    INT 21H
    INT 20H
    END START

    *

    دستور MOVSW

    دستور MOVSW دقيقا مانند MOVSB است با اين تفاوت كه بجاي يك بايت ، يك كلمه
    (َ2 بايت ) منتقل ميكند . براي انتقال دو بايت بين دو آدرس كافيست مانند
    عملياتي كه براي movsb توضيح داديم ، آدرسها را تنظيم كرده و از movsw استفاده
    كنيم .
    بعنوان مثال ، اگر بخواهيم در برنامه بالا بجاي movsbاز movswز استفاده كنيم ،
    بايد حلقه اي كه تشكيل داديم 10 بار اجرا شود:

    mov cx/10
    loop :_
    movsw
    loop loop _



    دستورات CLSو SLDو

    وقتي كه از movsbيا movswا استفاده ميكنيم ، مقدار ثباتهاي SIو DIو يكواحد
    افزايش پيدا ميكنند . در صورتي كه بخواهيم با اتقال هر بايت (يا كلمه ) مقدار
    اين ثباتها كاهش پيدا كنند، قبل از movsbيا movswا يك دستور SLD قرار ميدهيم .
    مثلا:

    SLD
    MOV CX/10 ; LOOP COUNTER
    LOOP :_
    MOVSB
    LOOP LOOP _


    دستور CLD عكس دستور SLD عمل كرده و مقدار ثباتهاي DIو SIو با انتقال هربايت يا
    كلمه ، يكواحد افزايش پيدا ميكنند. اين عمل بطور پيش فرض توسط movsbو movswو
    انجام ميشود ، با اينحال براي جلوگيري از تاثر SLD هاي قبلي و اطمينان بيشتر
    معمولا از آن استفاده ميشود.


    CLD
    MOV CX/10 ; LOOP COUNTER
    LOOP :_
    MOVSB
    LOOP LOOP _

    CLS

    *
    مخفف CLear Direction flagو SLDو مخفف Set Direction flag است .

    دستور REP
    براي راحتي كار و اينكه مجبور به ايجاد حلقه توسط دستور Loop نباشيم ، دستورالعمل REP
    در 8086 تعبيه شده . اين دستور مانند دستور Loop هر بار يكواحد از محتواي CX
    كم كرده و تا صفر شدن CX به تكرار عمليات ادامه ميدهد . در واقع REP يك
    دستورالعمل نبوده بلكه پيشوندي براي دستورات انتقال ( مانند movsb) است .
    بعنوان مثال براي انتقال 20 بايت از رشته S1 به رشته S2 ( مثال بالا) ميتوانيم
    حلقه را به اين صورت بنويسيم :

    CLD
    MOV CX/20
    REP MOVSB




    در قسمت بعد ، بقيه دستورات مربوط به رشته ها را باد ميگيريم .

  6. #26
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    دستورات مربوط به رشته ها

    دستورات REPNE/REPE/CMPSW/CMPSB/CMPS

    دستور CMPS براي مقايسه كردن دو رشته كاراكتري بكار ميرود. اين دستور دوبايت
    واقع در ESIو DS:SIو را با هم مقايسه كرده و فلاگها را براساس نتيجه تنظيم
    ميكند. سپس SIو DIو را افزايش (يا كاهش ) ميدهد. مثلا راي مقايسه كردن دو رشته
    كاراكتري Str1وStr2و به اينصورت عمل ميكنيم : str1 db 'This is a set of chars$'
    str2 db 'This is a set of chars$'

    دقت كنيد كه در اين مثال دو رشته محتواي يكسان دارند . پس از آن آدرس اولين
    رشته را در es:di و آدرس دومين رشته را در ds:si قرار ميدهيم .


    lea si/str1
    mov ax/ds
    mov es/ax
    lea di/str2



    پس از آن چون ميخواهيم از بايت اول تا انتهاي رشته (22 بايت ) را مقايسه كنيم
    ابتدا دستور CLS را براي افزاش si/di بكار برده ، و به شكل زير با تنظيم محتواي cx
    به 22 ، 22 بايت دو رشته را مقايسه ميكنيم :


    cld
    mov cx/22
    repe cmps str1/str2
    jne mis_match
    :
    :
    mis_mathc :
    :



    دستور Repe (مخفف Repeat while equal) تا زماني كه به اولين تفاوت برسد، بايتهاي
    دو رشته كاراكتري را با هم مقايسه ميكند . وقتي به اولين مورد تفاوت برسيم فلاگ
    وضعيت 1 شده و با دستور jne ميتوانيم به روال مورد نظر پرش كنيم .
    تفاوت CMPSبا CMPSBاو CMPSWو در اينست كه CMPS به با توجه به نوع تعريفي رشته
    ها عمل ميكند . يعني اگر رشته كاراكتري با تعريف DB ايجاد شده باشد، CMPS آندو
    را بايت با بايت ، و اگر بصورت DW تعريف شده باشند، بصورت كلمه به كلمه
    مقايسه ميكند .
    اما CMPSB هميشه دو رشته كاراكتري را بايت به بايت مقايسه ميكند . و همينطور CMPSW
    كه مقايسه را بصورت دوبايتي انجام ميدهد.
    مزيت مهم cmpsbو cmpswوبر cmpsر اينست كه cmpsb/ccmpsw احتياج به اپراند ندارند
    و تنها با اجراي cmpsbيا cmpswا بايتهاي لازم با هم مقايسه ميشوند .
    مثال بالا را با استفاده از cmpsb مينويسيم :


    :
    cld
    mov cx/22
    RepNe cmpsb
    je same
    different :
    :
    :



    ميبينيم كه در مقابل CMPSB هيچ اپراندي قرار ندارد . علاوه بر آن تغيير ديگري هم
    ملاحظه ميكنيم : اينكه بجاي Repeاز Repneز (مخفف Repeat until not equal) استفاده
    كرده ايم . RepNe تا وقتي كه به مورد مشابهي نرشد به مقايسه كردن رشته ها ادامه
    ميدهد . وقتي به دو بايت يكسان برسد فلاگ وضعيت را طوري تغيير ميدهد كه بتوانيم
    با JE به روتيني پرش كنيم كه ميخواهيم در صورت مساوي بودن رشته ها اجرا شود.
    (در مثال بالا به same جهش كرده ايم ) .

    دستورات SCAS/SCASB/SCASW

    اين دستورات بايت واقع در AL با كلمه واقع در AX را با بايت با كلمات واقع در
    رشته مقايسه ميكند . مانند CMPS، SCAS، به نوع تعريف رشته ها دقت ميكند و اگر
    بصورت DB تعريف شده باشند ، بايت به بايت و اگر بصورت DW تعريف شده باشند
    بصورت كلمه به كلمه جستجو ميكند . همچنين SCASBو SCASWو به اپراند احتياج ندارند
    و فقط با تنظيم آدرسهاي DS:SIو ES:SIو ميتوانند بايت يا كلمه مورد نظر را جستجو
    كنند.
    مثال .
    ميخواهيم برنامه اي بنويسيم كه محل اولين حرف 'a' را در رشته كاراكتري مورد نظر
    پيدا كنيم . بنابراين ابتدا رشته كاراكتري را تعريف ميكنيم :
    str db 'This is a sample text' ; 21 bytes .


    سپس آدرس رشته را در DSI ، و 'a' را در نيم ثبات AL قرار ميدهيم .
    mov al/'a'
    lea di/str


    پس از آن با عبارات زير عمل جستجو را آغاز ميكنيم . RepNe Scasb
    JNE out
    out
    روتيني است كه در صورت يافته نشدن رشته كاراكتري بايد به آنجا جهش كنيم و
    مثلا عبارتي مبني بر يافته نشدن رشته كاراكتري را چاپ كنيم . بدين ترتيب تمام
    رشته كاراكتري را براي يافتن 'a' جستجو ميكنيم و درصورتي كه حداقل يك حرف 'a'
    در رشته كاراكتري باشد ، با دستور JNE Out به روتين لازم جهش ميكنيم .

    ليست كامل :


    .286c
    .MODEL SMALL
    .CODE
    ORG 100h
    START:
    JMP MAIN
    STR1 DB 'This is a sample String' ; 25 Bytes
    FOUND DB 'Match case found$'
    NFOUND DB 'No Match case found$'
    MAIN:
    LEA DI/STR1
    MOV CX/25
    MOV AL/'a'
    REPNE SCASB
    JE OUT_
    MOV AH/9
    LEA DX/NFOUND
    INT 21H
    INT 20h
    OUT:_
    LEA DX/FOUND
    MOV AH/9
    INT 21H

    INT 20H
    END START

  7. #27
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    استفاده از ماوس

    ے كاركردن با ماوس ساده تر و سريع تر از كار كردن با صفحه كليد است . بهمين علت
    داشتن امكانات بكارگيري ماوس در برنامه ها، يك امتياز مهم محسوب ميشود.
    ے براي اينكه برنامه اي بتواند از ماوس استفاده كند، بايد درايور مخصوص ماوس كه
    ے عبارت از يك برنامه COM. (مانند MOUSE.COM) است را اجرا كنيم . اين درايور ها
    روتينهاي مخصوص ماوس را در اينتراپت 33h لود ميكنند.
    ے براي استفاده از ماوس ، پس از بارگذاري درايور مخصوص ، بايد ان درايور را فال
    كنيم ، اين كار را با استفاده از سرويس 00h از وقفه 33h انجام ميدهيم :

    براي اجرا باز ميگرداند

    AX=0 =AX كد خطا
    ے اگر راه اندازي ماوس موفقيت آميز باشد ، پس از فراخواني AX=0 خواهد بود در غير
    ے اينصورت ، مثلا در مواقعي كه درايور ماوس نصب نشده باشد، AX حاوي كد خطا خواهد
    بود.
    ے مثال : اين برنامه ماوس را در صورت وجود راه اندازي ميكند و در صورت وقوع خطا
    به نقطه لازم پرش ميكند: XOR AX/AX ;
    INT 33H ;

    آيا كد خطا وجود دارد? ; CMP AX/0
    بله ، پرش به روتين خطا ; JNZ ERROR

    ے بعد از آن بايد مكان نماي ماوس را نمايش بدهيم . براي اينكار كافيست كه AX را
    برابر 1 قرار داده و INT 33h را اجرا كنيم . MOV AX/1
    INT 33h


    ے در صورتيكه درايور ماوس نصب يا راه اندازي نشده باشد، نتايج غير قابل پيش بيني
    رخ خواهد بدست خواهد آمد.
    ے به همين سادگي هم ميتوان مكان نماي ماوس را مخفي كرد. براي مخفي كردن مكان نماي
    ماوس AX را برابر 2 تنظيم كرده و INT 33h را اجرا ميكنيم . MOV AX/2
    INT 33h

    ے بايد توجه كنيم كه اين سرويس را در حالتي كه مكان نماي ماوس فعال نيست اجرا
    ے نكنيم . در صورتي كه عمل مخفي كردن مكان نماي ماوس را 2 بار انجام دهيم ، براي
    ے ظاهر كردن آن هم بايد 2 بار متوالي سرويس راه اندازي مكان نماي ماوس را اجرا
    كنيم .

    ے در هنگام كار با ماوس لازم داريم كه موقعيت مكان نماي آن و هم چنين وضعيت
    كليدهائي از ماوس كه فشرده يا رها شده اند را بدانيم .
    ے براي دريافت اطلاعات ماوس از سرويس 3 وقفه 33h ، با پارامتر هاي زير استفاده
    ميشود :
    براي فراخواني برگردانده ميشود

    AX=3 BX=0 هيچ دكمه اي فشرده نشده
    BX=2 دكمه چپ فشرده شده است
    BX=2 دكمه راست فشرده شده است
    BX=3 هردو دكمه فشرده شده اند
    CX: ستون فعلي مكان نما
    DX: سطر فعلي مكان نما

    ے همانطور كه ميبينيد، بعد از فراخواني وقفه ، رجيستر BX مشخص ميكند كه كدام
    ے كليد(يا كليدها) فشرده شده اند. هم چنين موقعيت سطر و ستون مكان نما بر حسب
    Pixel
    بدست مي آيد.
    ے بعنوان مثال اگر از ماوس در محيط گرافيكي با وضوح 480 َ640 استفاده ميكنيد ،
    ے مقادير CXو DXو به ترتيب 640 و 480 خواهند بود . براي حالت متني كافيست كه
    ے مقادير بدست آمده با CXو DXو را به 8 تقسيم و با 1 جمع كنيم تا موقعيت مكان
    نما بر حسب سطر و ستون متني (Text) بدست بيايد.
    مثال :


    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    JMP MAIN
    MSG DB ' Press the Left Mouse Key to Terminate'/13/10/'$'
    MAIN:
    XOR AX/AX
    INT 33H
    MOV AX/1
    INT 33H
    MOV AX/3
    LOOP:_
    INT 33H
    CMP BX/1
    JNZ LOOP_
    MOV AX/

  8. #28
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    بكارگيري Mouse

    ے وقتي كه از سرويس 3h براي دريافت وضعيت ماوس استفاده ميكنيم ، تنها ميتوانيم
    ے وضعيت ماوس در لحظه اجراي سرويس را بدست بياوريم . راه بهتر اينست كه از
    ے سرويس 5h كه اعمال ماوس را در يك "صف " قرار ميدهد استفاده كنيم . در اين
    ے حالت نيازي نيست كه اطلاعات فشرده شدن كليد را درست در همان لحظه دريافت كنيد
    بلكه ميتوانيد آن را از "صف " برداريد.

    سرويس 5h ، خواندن صف ماوس برميگردآند

    AX=5 :BX تعداد دفعات فشرده شدن كليد ماوس
    BX : 1: براي اطلاعات دكمه چپ :CX ستون فعلي مكان نما
    0 براي اطلاعات دكمه راست X سطر فعلي مكان نما

    ے اين سرويس به ما امكان ميدهد كه بدانيم دكمه مورد نظر بعد از آخرين دريافت
    ے وضعيت چند مرتبه فشرده شده است . بهمين ترتيب ميتوانيم مختصات فعلي ماوس را
    هم بدست بياوريم .
    ے روش كار به اينصورت است كه ابتدا با قرار دادن 1يا 0ا در ثبات BX معلوم ميكنيم
    ے كه اطلاعات كدام كليد را ميخواهيم دريافت كنيم . بعد از اجراي وقفه ، اطلاعات
    ے كليد درخواستي از طريق ثبات BX و مختصات فعلي مكان نماي ماوس از طريق CX/DX
    بدست مي آيد .

    مثال :
    ے اين مثال منتظر ميماند كه شما يكي از كليد هاي ماوس را فشار دهيد و در نهايت
    به شما اعلام ميكند كه چند بار كليد سمت راست را فشار داده ايد.

    .MODEL SMALL
    .CODE
    ORG 100H
    START :JMP TOP
    ANSWER DB " Number of times right botton was pressed"
    TOP:
    XOR AX/AX
    INT 33H

    MOV AX/1
    INT 33H

    MOV AH/7
    INT 21H ; WAIT FOR A KEY

    MOV BX/1
    MOV AX/5
    INT 33H

    LEA DX/ANSWER
    MOV AH/9
    INT 21H

    INT 20H
    END START



    ے سرويس 5h هنوز هم داراي محدوديتي است . به اين ترتيب كه موقعيت مكان نما در
    ے زمان اجراي وقفه را برميگرداند. به همين خاطر مجبور خواهيد بود كه مرتبا با اجراي
    ے اين سرويس ، اطلاعات ماوس را دريافت كنيد . براي حل اين مشكل از سرويس 6 كه
    مكمل سرويس 5h است استفاده ميكنيم .

    سرويس 6h از اينتراپت 33h

    بايد تنظيم كنيم برميگرداند

    AH=6h BX تعداد دفعات رها شدن دكمه ماوس
    BX=1
    اطلاعات دكمه چپ CX شماره ستون مكان نما در آخرين رها شدن
    BX=0 اطلاعات دكمه راست DX شماره سطر مكان نما در آخرين رها شدن

    ے مانند سرويس 5h بايد با قرار دادن 0يا 1ا در ثبات BX معلوم كنيم كه اطلاعات
    ے كدام كليد را لازم داريم . اگرBX=1 باشد اطلاعات دكمه سمت چپ و در غير اينصورت
    اطلاعات دكمه سمت راست بدست مي آيد.
    ے بعد از فراخواني وقفه ، ثبات BX معلوم ميكند كه دكمه مورد نظر ، بعد از آخرين
    ے دريافت وضعيت چند بار رها شده است . در مواقعي كه ميخواهيم چيزي را با ماوس
    ے روي صفحه نمايش حركت بدهيم (مانند حركت دادن يك آيكون در ويندوز) رها شدن
    دكمه هاي ماوس را هم بايد در نظر بگيريم .

    حركت دادن مكان نماي ماوس


    بعلاوه ميتوانيم مكان نماي ماوس را در موقعيت خاصي از صفحه نمايش قرار بدهيم .
    كافيست كه از سرويس 4h به اين شكل استفاده كنيم . AX=4h

    CX ستون جديد مكان نما
    DX سطر جديد مكان نما

    بعد از اجراي وقفه ، مكان نماي ماوس در محل مورد نظر قرار ميگيرد.
    مثال :

    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    XOR AX/AX
    INT 33H

    MOV AH/7
    INT 21H

    XOR CX/CX
    XOR DX/DX
    MOV AX/4
    INT 33H

    MOV AH/7
    INT 21H

    INT 20H
    END START


    مويد باشيد

  9. #29
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    بكارگرفتن فايلها
    ے تا قبل از DOS V.2 سيستم عامل داس براي كنترل فايلها از (Control Block
    ے File)FCB استفاده ميكرد . اطلاعات هر فايل (شامل نام ، طول ، مسير و ... ) در
    ے FCB قرار داشت و اين باعص ميشد نام فايل هميشه به 12 حرف محدود باشد. بنا
    ے براين امكان ذكر مسير فايل به همراه اسم آن نبود . مثلا نميشد فايل SAMPLE.DAT
    ے كه در C:\ قرار داشت را بصورت C:SSAMPLE.DAT نوشت . به همين دليل با انجام
    ے تغيراتي در ساختار فايل گرداني DOS ، شناسه فايل (File Handle) ابداع شد و در
    نگارشهاي 3/3 به بالاي DOS مورد استفاده قرار گرفت .
    ے شناسه فايل يك كلمه (Word) 16 بيتي و معرف يك فايل در DOS است . هنگامي كه
    ے ميخواهيد با فايلي كاركنيد ، نام آن را به DOS ميدهيد و DOS يك File Handle
    به شما ميدهد . بعد از آن فقط با شناسه فايل كار داريم .

    ے DOS بهمراه وقفه مخصوص خودش (Int 21h) ، سرويسهائي را بهمراه دارد كه براي
    كاربا فايلها بكار ميرود .
    ے اساسي ترين كار اينست كه بتوانيم يك فايل ايجاد كنيم . براي ايجاد فايل از
    سرويس 3Ch به شكل زير استفاده ميكنيم .
    AH=3CH

    خصوصيات فايل CX=
    اشاره به رشته كاراكتري محتوي نام فايل و مختوم به 0: DSX:

    ے نام فايل بايد حتما به كاراكتر اسكي 0 مختوم باشد . CX مشخص كننده خصلت فايل
    است و از جدول زير بدست مي آيد :
    0
    : فايل ساده 1
    : فايل فقط خواندني 2
    : فايل مخفي 4
    : فايل سيستمي 8
    : اسم ديسك اين خصلت را دارد 10h
    : سابدايركتوري

    ے مثال : در اين مثال يك فايل به اسم DUMMY.TXT ميسازيم . بعد از اجراي برنامه اگر
    ے دستور DIR در سيستم عامل را اجرا كنيد ، فايلي به اسم DUMMY.TXT با طول صفر بايت
    مشاهده ميكنيد.


    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    JMP MAIN
    FILE DB 'DUMMY.TXT'/0
    MAIN:
    LEA DX/FILE
    MOV AH/3CH
    XOR CX/CX
    INT 21H
    INT 20H

    END START




    ے قدم بعدي نوشتن اطلاعات در فايل است . براي نوشتن در فايل ابتدا شناسه فايل را در
    ے BX قرار ميدهيم . موقعيت محلي از حافظه كه داده ها از آن خوانده خواهند شد
    ے با DSX و تعداد بايتهائي كه بايد منتقل شود با CX مشخص ميشود. در نهايت بايد
    سرويس 40h را اجرا كنيم .
    AH= 40H

    اشاره به بافر DSX=
    تعداد بايتها براي نوشتن CX=
    شناسه فايل BX=

    ے هر وقت يك فايل را ايجاد يا باز ميكنيم ، بايد آن را ببنديم مقداري از داده هاي
    ے آن كه در حافظه مانده اند در فايل نوشته شده و حافظه اختصاص يافته به آن هم آزاد
    ے شود . براي بستن يك فايل شناسه فايل را در BX قرار داده و وقفه 21h را با AH=3Eh
    اجرا ميكنيم .

    مثال :
    ے قبلا در برنامه نويسي سيستم تصوير ديديم كه صفحه نمايش VGA در حالت 80x25
    ے شامل 4000 بايت (80x25x2) براي كاراكتر و مشخصه است كه از آدرس 0000:َB800 شروع
    ے ميشود . در اين مثال برنامه اي مينويسيم كه كل صفحه نمايش را از اين محل خوانده
    و در فايل DUMMY.TXT ذخيره كند.


    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    JMP MAIN
    BUF DB 4000 DUP(0)
    FILE DB 'DUMMY.TXT'/0
    HANDLE DW 0
    MAIN:
    LEA DX/FILE
    MOV AH/3CH
    XOR CX/CX
    INT 21H
    MOV HANDLE/AX

    PUSH ES
    MOV AX/DS
    MOV ES/AX
    LEA DI/BUF
    PUSH DS
    MOV AX/0B800H
    MOV DS/AX
    XOR SI/SI
    MOV CX/4000
    REP MOVSB
    POP DS
    POP ES

    MOV AH/40H
    MOV BX/HANDLE
    MOV CX/4000
    LEA DX/BUF
    INT 21H

    MOV AH/3EH
    INT 21H

    INT 20H
    END START



    ے ما همچنين ميتوانيم داده هاي يك فايل را بخوانيم و در محل خاصي از حافظه (معروف
    ے به Buffer) قرار دهيم . براي خواندن از فايل سرويس 3Fh را با اين پارامترها بكار
    ميبريم .
    AH=3FH

    شناسه فايل BX=
    تعداد بايتها براي خواندن CX=
    آدرس بافر براي انتقال داده هاDSX=

    ے مثال : حالا برنامه اي مينويسيم كه فايل DUMMY.TXT ايجاد شده در مثال قبل را
    ے خوانده و داده هاي آن را به بافر صفحه تصوير منتقل كند . به اين ترتيب محتواي
    ے صفحه نمايش كه در هنگام اجراي SAVEFILE.COM ( برنامه مثال قبل ) ذخيره شده بود ،
    مجددا نمايش داده ميشود.


    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    JMP MAIN
    BUF DB 4000 DUP(0)
    FILE DB 'DUMMY.TXT'/0
    HANDLE DW 0
    MAIN:
    LEA DX/FILE
    MOV AH/3DH
    MOV AL/0 ; READ-ONLY
    INT 21H
    MOV BX/AX

    MOV AH/3FH
    MOV CX/4000
    LEA DX/BUF
    INT 21H

    LEA SI/BUF
    PUSH ES
    MOV AX/0B800H
    MOV ES/AX
    XOR DI/DI
    MOV CX/4000
    REP MOVSB
    POP ES

    MOV AH/3EH
    INT 21H

    INT 20H
    END START

  10. #30
    آخر فروم باز Nesta's Avatar
    تاريخ عضويت
    Jan 2005
    محل سكونت
    tehran
    پست ها
    3,343

    پيش فرض

    دسترسي به پورتهاي كامپيوتر

    تا اينجا برنامه نويسي خيلي از اجزاي كامپيوتر مثل صفحه كليد ، صفحه نمايش ،
    ديسك و .. را ديديم . براي برنامه ريزي اينها از وقفه هاي BIOSيا DOSا استفاده
    كرديم . وقفه هاي ياد شده همه زير برنامه هائي هستند كه به محض اجرا ، زير
    برنامه هاي ديگري كه در بخشي از ROM كامپيوتر قرار دارند را به اجرا در مي
    آورند . اين بخشها همگي داراي آدرسهائي هستند كه خارج از حوزه آدرس دهي CPU
    قرار دارند . يعني نميتوان با الگوي Segment:Offset به آنها دسترسي پيدا كرد . در
    عوض داراي شماره خاصي هستند كه به شماره Port معروفست . از طريق اين پورتها
    ميتوانيم مستقيما و بدون واسطه به راهبري اجزاي كامپيوتر بپردازيم . مثلا ميتوانيم
    با استفاده از پورت شماره 60h ، كار صفحه كليد را كنترل كنيم يا اينكه پورتهاي
    ...37Ah/379h/ به كنترل پورت موازي و چاپگر بپر دازيم . همينكار را وقفه 17h
    (دسترسي به چاپگر) هم انجام ميدهد اما اين وقفه فقط براي كار با چاپگر طراحي شده
    و نميتوانيم با استفاده از آن كار ديگري انجام بدهيم .

    دستورات مربوط به پورتها

    به هر پورتي ميتوان يك عدد تك بايتي فرستاد يا از آن خواند. براي نوشتن
    در يك به روش زير عمل ميكنيم :
    1- اگر عدد پورت كوچكتر از 255 باشد ، ميتوانيم با استفاده از دستور OUT و
    بطور مستقيم عدد را به پورت بفرستيم . يعني بصورت OUT Portnumber/Value

    مثال : OUT 80h/60
    2
    - اگر عدد مربوط به پورت از 255 ( يك بايت ) بيشتر باشد ، بايد ابتدا آن
    را در ثبات DX قراردهيم ، سپس با استفاده از OUT ، مقدار را به پورت
    بنويسيم .
    مثلا براي نوشتن در پورت 3F8h ابتدا آن را در DX قرار ميدهيم و بعد عدد
    را به پورت مشخص شده با DX انتقال ميدهيم . mov dx/3F8h
    out dx/0FFh


    در اين حالت يك بايت قابل انتقال است . براي ارسال يك عدد دوبايتي بايد
    به سراغ نيم ثبات AL برويم . به اينصورت كه ابتدا 8 بايت سمت پائين
    (سمت راست ) را در AL قرار داده و به پورت ميفرستيم . بعد بلافاصله 8 بايت
    بالا را به همين ترتيب در پورت قرار ميدهيم . مثلا فر ض كنيد ميخواهيم عدد 0AFDh
    را به پورت 61h بفرستيم :


    mov ax/0AFDh
    out 61h/al
    shr ax/8
    out 61h/al



    براي خواندن پورت هم اگر شماره پورت از 255 بزرگتر باشد ، آن را در DX قرار
    ميدهيم . وقتي ميخواهيم پورتي را بخوانيم ، بايد حتما اين كار را با كمك نيم
    ثبات AL ، و با استفاده از دستور IN انجام دهيم . يعني بصورت :
    IN AL/PortNo .


    مثلا براي خواندن پورت 71h ، عبارت IN AL/71h را بكار ميبريم .

    مثال :
    عددي كه در پورت 61h قرار دارد براي بكار انداختن بلند گوي كامپيوتر بكار ميرود
    ( و برعكس براي از كار انداختن ) . اگر 3 بيت انتهائي آن 1 باشند ، بلندگوي
    كامپيوتر ( با مشخصاتي كه در پورت هاي 41h و 43h قرار ميدهيم ) شروع به توليد
    صوت ميكند . و اگر آن بيتها را بازهم 0 كنيم ، بلندگوي كامپيوتر از كار باز مي
    ايستد . در اين برنامه بلند گوي كامپيوتر به كار مي افتد و بعد از فشردن يك
    كليد مجددا" خاموش ميشود.


    .MODEL SMALL
    .CODE
    ORG 100H
    START:
    IN AL/61H
    OR AL/00000111B
    OUT 61H/AL

    XOR AH/AH
    INT 16H

    IN AL/61H
    AND AL/11111000B
    OUT 61H/AL

    INT 20H
    END START

Thread Information

Users Browsing this Thread

هم اکنون 1 کاربر در حال مشاهده این تاپیک میباشد. (0 کاربر عضو شده و 1 مهمان)

User Tag List

قوانين ايجاد تاپيک در انجمن

  • شما نمی توانید تاپیک ایحاد کنید
  • شما نمی توانید پاسخی ارسال کنید
  • شما نمی توانید فایل پیوست کنید
  • شما نمی توانید پاسخ خود را ویرایش کنید
  •