1. مهمان گرامی، جهت ارسال پست، دانلود و سایر امکانات ویژه کاربران عضو، ثبت نام کنید.
    بستن اطلاعیه

اسمبلی یاد بگیریم

شروع موضوع توسط minaaa ‏23/10/11 در انجمن Assembly

  1. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,773
    تشکر شده:
    6,457
    امتیاز دستاورد:
    113
    پاسخ : اسمبلی یاد بگیریم

    حتما با ثابتها در زبانهائی مثل پاسکال آشنائی دارید . بعنوان مثال با جمله
    ے Const MaxLen=1024; ، ثابتی بنام MaxLen تعریف شده و مقدار آن برابر ۱۰۲۴ قرار
    ے قرار میگیرد . پس از آن کامپایلر در هرجا که MaxLen را مشاهده کند عدد ۱۰۲۴ را
    بجای آن قرار میدهد .
    در زبان اسمبلی برای تعریف یک ثابت از معرفه EQU به شکل زیر استفاده میکنیم

    مقدار EQU نام ثابت
    مثلا : MaxLen EQU 1024
    ے به این ترتیب اسمبلر همیشه بجای MaxLen عدد ۱۰۲۴ را قرار میدهد . بهمین دلیل
    ثابتهای برنامه را باید قبل از جمله CODE. بنویسیم . مثال :

    . MODEL SMALL
    SECTORS EQU 18
    SIDES EQU 2
    . CODE
    :
    :

    ے به این خاطر ثابتها را قبل از CODE. تعریف میکنیم که در برنامه کامپایل شده اثری
    از نام ثابت نبوده بلکه مقدار هر ثابت در جای لازم قرار گرفته است .
    مثال :

    . MODEL SMALL
    BELL EQU 7
    . CODE
    ORG 100H
    MOV AH/0EH
    MOV AL/BELL
    INT 10H
    INT 20H
    END

    متغیرها

    ے از متغیرها برای نگهداری موقتی داده ها استفاده میکنیم . مثلا در زبان پاسکال
    ے میتوانیم با عبارت Var یک متغیر تعریف کنیم مثل Var Buffer:Byte; و در زبان
    سی مثل unsigned char Buffer; .
    ے متغیرها در زبان اسمبلی باید حتما در داخل قطعه داده (DS) تعریف بشوند و در
    ے برنامه های COM. هم از آنجائی که قطعه داده ها و کد یکی است میتوانیم در قطعه کد
    نیز تعریف کنیم .
    ے برای تعریف یک متغیر باید بعد از نام آن یکی از عبارات ..DB/DW/DD/ را
    ے بیاوریم . DB مشخصه نوع بایت ،DW مشخصه نوع Word (دوبایتی ) و DD مشخصه نوع
    (Double Word) 4 بایتی است .
    مثلا :

    . CODE
    SIZE DW 1024
    BELL DB 7

    ے در این مثال Size یک متغیر دو بایتی بوده و مقدار اولیه ان ۱۰۲۴ است و BELL نیز
    یک متغیر تک بایتی با مقدار ۷ میباشد .
    ے اگر نمیخواهیم به متغیر مقدار اولیه بدهیم ، میتوانیم از علامت (?) بجای مقدار
    استفاده کنیم مانند : MaxLen DW ?

    ے برای تعریف یک رشته کاراکتری از معرفه DB استفاده کرده و محتوای رشته را داخل
    (”) یا (“”) قرار میدهیم . مثلا :

    MSG DB “ASSEMBLY / A QUICK LOOK ! “

    ے در این مثال MSG یک متغیر کاراکتری است . در اسمبلی میتوانیم از کد اسکی
    ے کاراکتر ها نیز استفاده کنیم . مثلا اگر در تعریف DB بخواهیم کدهای اسکی ۱۳و ۱۰
    را به MSG اضافه کنیم میتوانیم با کاما این کار را انجام دهیم :

    MSG DB “ASSEMBLY / A QUICK LOOK ! “/13/10

    یا : MSG DB “ASSEMBLY / A QUICK LOOK ! “/0Ah/0Dh

    یا حتی : MSG DB “ASSEMBLY / A QUICK LOOK ! “/0Ah/0Dh/’$’

    این ترکیبها همه یک رشته کاراکتری معرفی میکنند .

    برای تعریف آرایه ها نیز از روشی مشابه و به شکل زیر استفاده میکنیم :

    (مقدار اولیه )DUP تعداد عناصر DB/DW/DD نام متغیر
    مانند: BUFFER DB 1024 DUP(0 )

    که ارایه ای یک کیلوبایتی تعریف کرده و همه عناصر آن را با ۰ پر میکند.
    اگر نخواهیم مقدار اولیه ای در نظر گرفته شود از ? استفاده میکنیم .
    مانند: BUFFER DB 1024 DUP(? )

    و برای تعریف یک آرایه حرفی باید با یک حرف یا عبارت آن را پر کنیم : BUFFER DB 1024 DUP(“A” )

    و حتی : BUFFER DB 1024 DUP(“STACK” )

    ے گفتیم که متغیرها همیشه (در برنامه های COM.) در قطعه کد و بعد از CODE. نوشته
    ے میشوند ، بنا براین اسمبلر همیشه سعی خواهد کرد که آنها را بصورت یک کدماشین
    ے قابل اجرا تفسیر کند. به همین دلیل همیشه بایک دستور JMP از روی آنها پرش
    میکنیم . مثال :

    . MODEL SMALL
    RDISK EQU 2
    . CODE
    ORG1 100H
    START :
    JMP MAIN
    BUFFER DB 512 DUP(0 )
    MSG DB “DISK DUP.”/13/10/’$’
    MAIN :

    مجموعه کدهای اجرایی برنامه :
    : END START

    همانطور که میبینید با دستور JMP MAIN از قسمت تعریف داده ها پرش کرده ایم .

    در قسمت بعد نحوه استفاده از متغیرها و بافرها (Buffers) را مطالعه
    میکنیم . با همین معلومات برنامه ای برای نمایش محتوای سکتوهای دیسک
    مینویسیم و پیغامهای لازم را به آن اضافه میکنیم
     
  2. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,773
    تشکر شده:
    6,457
    امتیاز دستاورد:
    113
    پاسخ : اسمبلی یاد بگیریم

    در این قسمت نحوه دسترسی به مقادیر متغیر ها را یاد میگیریم .
    ے وقتی که میخواهیم مقدار یک متغیر را به یک متغیر یا ثبات دیگر منتقل کنیم باید
    ے به اندازه آن توجه داشته باشیم . مثلا اگر متغیری بصورت LOCATE DB 10 تعریف کرده
    ے باشیم ، به دلیل تک بایتی بودن ، نمیتوانیم آن را به یک ثبات کامل مثل AX یا
    متغیر دوبایتی که با DW تعریف شده است ارسال کنیم .
    ے اما انتقال آن به یک نیم ثبات مثل ALیا AHا و … مجاز است مانند . MOV BH/LOCATE

    ے از متغیرها بیشتر برای نگهداری موقت داده ها استفاده میشود . مثلا وقتی که
    ے برنامه ای برای کار با قطاعهای دیسک مینویسیم ، باید یک محل موقتی برای ذخیره
    ے محتوای قطاع های خوانده شده ایجاد کنیم . در این موقع یک متغیر به شکل (ترجیحا)
    آرایه تعریف میکنیم .
    ے وقتی به این شکل با متغیرها برخورد میشود، به دانستن آدرس آن نیاز پیدا میکنیم
    فرض کنید میخواهیم جمله A QUICK START TO ASSEMBLY PROGRAMMING را چاپ کنیم .
    در قدم اول باید متغیری تعریف کرده و این جمله را داخل آن قرار دهیم .
    پس : MSG DB ‘A QUICK START TO ASSEMBLY PROGRAMMING’/13/10/’$’

    ے اعداد ۱۳وَ۱۰ انتهای رشته برای انتقال مکان نما به سطر بعد هستند و کاراکتر ‘$’
    ے از این جهت وجود دارد که تابع چاپ رشته انتهای رشته کاراکتری را با بودن $
    تشخیص میدهد.
    ے برای چاپ رشته کاراکتری راه هائی وجود دارد که یکی از آنها استفاده از تابع ۹h
    مربوط به INT 21h میباشد .
    برای فراخوانی آن باید به این صورت رجیستر ها را پر کنیم : AH=09H

    آدرس رشته کاراکتری DS:DX = INT 21H

    ے عبارت DS:DX نشان میدهد که مقدار قطعه (Segment) رشته کاراکتری ، یعنی آن قطعه
    ے ای که متغیر تعریف شده در آن قرار گرفته است ، را باید در DS قرار بدهیم . به
    همین صورت نیز مقدار آفست (Offset) آن را به DX انتقال میدهیم .
    برای بدست آوردن شماره قطعه یک متغیر از عملگر SEG استفاده میکنیم .
    ے مثلا برای بدست آوردن شماره قطعه MSGاز MOV AX/Seg MSGز استفاده میکنیم . این
    دستور شماره سگمنت MSG را پیدا کرده و در AX قرار میدهد .
    برای بدست آوردن شماره آفست هم از OFFSET استفاده میکنیم مثلا MOV DX/OFFSET MSG
    پس برای چاپ رشته MSG باید به این صورت عمل کنیم :

    MOV AH/09H
    MOV DX/OFFSET MSG
    INT 21H

    ے این قطعه کاری که ما میخواهیم را انجام میدهد و اگر دقت کنید متوجه میشوید که
    ے اصلا شماره قطعه (Segment) را محاسبه نکرده ایم . علت اینست که متغیر ما به دلیل
    ے COM. بودن برنامه در Code Segment ( که با CODE. مشخص میشود) تعریف شده پس خود
    ے بخود DS حاوی مقدار سگمنت آن هست . ( باز هم یاد آوری میکنیم که CS حاوی شماره
    ثبات کد و DS حاوی ثبات داده ها است و در برنامه های COM. مقدار برابر دارند)

    ے یک دستور خلاصه برای بدست آوردن عدد آفست وجود دارد بنام LEA .کل کاری که این
    ے دستورالعمل انجام میدهد اینست که دیگر احتیاج به نوشتن OFFSET نخواهد بود . به
    عنوان مثال MOV DX/OFFSET MSGبا LEA DX/MSGا برابر است .
    با این تفاسیر کل برنامه به این شکل خواهد بود .

    . MODEL SMALL
    . CODE
    ORG 100H
    START :
    JMP MAIN ; skip to main codes
    MSG DB ‘A QUICK START TO ASSEMBLY PROGRAMMING’/13/10/’$’
    MAIN :
    LEA DX/MSG ; get MSG offset
    MOV AH/09 ; write string function
    INT 21H ; call interrupt 21h
    INT 20H ; terminate program
    END START

    تمرین :
    ے برای اینکه تمرین بهتری داشته باشیم ، میخواهیم خودمان و فقط با استفاده از وقفه
    ے مربوط به چاپ کاراکتر همین جمله را چاپ کنیم . قبلا گفتیم که تابع ۰Eh از وقفه
    ے ۱۰h یک کاراکتر را در محل مکان نما چاپ کرده و مکان نما را یک خانه به راست
    انتقال میدهد. میخواهیم رشته کاراکتری بالا را تا رسیدن به علامت $ چاپ کنیم .
    ے بهترین کار اینست که عدد آفست را در BX قرار بدهیم . در اینموقع آفست اولین
    ے کاراکتر در BX است . مقدار داخل این آفست را بصورت MOV al/[bx] به ثبات AL
    ے منتقل کرده و بعد چاپ میکنیم . برای کاراکتر بعدی یکواحد به BX اضافه میکنیم و
    ے دوباره همان کارهای قبلی … . این عملیات را باید تا رسیدن به کاراکتر ‘$’ ادامه
    بدهیم .
    ے ** این برنامه را خودتان و بدون توجه به راه حل ارائه شده بنویسید و فایل COM.
    آن را بسازید.
    . MODEL SMALL
    . CODE
    ORG 100H
    START :
    JMP MAIN ; jump to MAIN
    MSG DB ‘A QUICK START TO ASSEMBLY PROGRAMMING’/13/10/’$’
    MAIN :
    LEA BX/MSG ; get MSG offset
    MOV AH/0EH ; write char function
    LOOP :_
    MOV AL/[BX] ; move [BX] to AL: charactre code
    CMP AL/’$’ ; if al is equal with ‘$’
    JE END _; then jump to END _
    INT 10H ; otherwise call interrupt 10h
    INC BX ; BX=BX+1
    JMP LOOP _; jump to next caharcter
    END :_
    INT 20H ; terminae program
    END START
     
  3. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,773
    تشکر شده:
    6,457
    امتیاز دستاورد:
    113
    پاسخ : اسمبلی یاد بگیریم

    در این قسمت یک تمرین جدید انجام داده و بوسیله آن تجربیات خودمان را افزایش
    میدهیم . این تمرین اولین برنامه ما هست یک عملیات سطح پائین سیستم ، یعنی
    دسترسی به دیسک ، را انجام میدهد .

    تابع شماره ۲(AH=2() از وقفه ۱۳h که وقفه دیسک میباشد ، برای خواندن سکتورهای
    دیسک بکار میرود . وقتی شماره هد، شیار،سکتور و … را مشخص کرده و وقفه را
    فراخوانی نمودیم ، محتوای قطاع خوانده شده در محلی که با جفت ثبات ES:BX مشخص
    میشود قرار میگیرد. به همین دلیل ما یک آرایه تعریف میکنیم وآدرس آن را در ES:BX
    قرار میدهیم تا اطلاعات خوانده شده در آن قرار بگیرد. BUF DB 512 DUP(0)

    در این مثال ما میخواهیم برنامه ای بنویسیم که محتوای قطاع بوت کننده دیسکی را
    خوانده و نمایش دهد . چون میخواهیم یک سکتور را بخوانیم و اندزه هر قطاع ۵۱۲
    بایت است ، پس آرایه ای با ۵۱۲ عنصر تک بایتی تعریف کرده ایم .
    در قدم بعدی شماره شیار (۰-۷۹) را در CH، شماره قطاع (۱-۱۸) را در CL، شماره
    درایو را در DL(…/.:0=A ) ، رویه دیسک را در DH(0=1st Side() و تعداد قطاعهائی
    که باید خوانده شوند را در AL قرار میدهیم .

    MOV AX/0201H
    MOV CH/0 ;TRACK NUMBER
    MOV CL/1 ;SECTOR NUMBER
    MOV DH/0 ; SIDE #1
    MOV DL/0 ; 0=A / 1=B /( …DRIVE NUMBER )

    حالا باید آدرس بافر تعریف شده (BUF) را به ES:BX منتقل کنیم . گفتیم که برای
    بدست آوردن شماره سگمنت هر متغیر از Seg و برای بدست آوردن مقدار آفست از Offset
    استفاده میکنیم . چون برنامه ما COM. است ، پس عدد سگمنت بطور خودکار در
    ثبات DS هست و احتیاجی به یافتن آن نداریم . بلکه فقط باید آن را به ES منتقل
    کنیم .
    گفتیم که نمیتوانیم ثبات ESو DSو را مستقیما و با MOV به هم منتقل کنیم ، بلکه
    باید از یک ثبات همه منظوره مثل AX کمک بگیریم . بنا براین و برای اینکه مقدار
    فعلی ثبات AX از بین نرود، ابتدا AX را در Stack قرار داده و مقدار DS را در آن
    قرار میدهیم : PUSH AX ; SAVE AX
    MOV AX/DS

    و پس از آن محتوای AX را به ES داده و دوباره مقدار AX را از پشته POP میکنیم : MOV ES/AX
    POP AX

    پس از آن با دستور LEA مقدار آفست BUF را بدست می آوریم : LEA BX/BUF

    و در نهایت فراخوانی اینتراپت ۱۳h. INT 13H

    بقیه برنامه عبارتست از چاپ کارارکترهای داخل آرایه BUF که قبلا آن را یاد
    گرفتیم . فقط به این نکته توجه میکنیم که کدهای اسکی کوچکتر از ۳۲ کدهای کنترلی
    بوده و به جای آنها باید کاراکتر (.) چاپ کنیم به همین دلیل هم قطعه کدی برای آن
    نوشته ایم :

    MOV AL/BUF[BX]
    CMP AL/32
    JB SKIP
    :
    :
    SKIP :
    MOV AL/’.’
    INT 10H
    :
    :

    لیست کامل : .MODEL SMALL
    .CODE
    ORG 100H
    START:
    JMP MAIN
    BUF DB 512 DUP(0)
    MAIN:
    MOV AX/0201H
    MOV CH/0 ;TRACK NUMBER
    MOV CL/1 ;SECTOR NUMBER
    MOV DH/0 ; SIDE #1
    MOV DL/0 ; 0=A / 1=B /( …DRIVE NUMBER)
    PUSH AX ; SAVE AX
    MOV AX/DS
    MOV ES/AX
    POP AX
    LEA BX/BUF
    INT 13H

    MOV BX/1
    MOV AH/0EH ; WRITE CHAR.
    PRINT:
    MOV AL/BUF[BX]
    CMP AL/32
    JB SKIP
    INT 10H
    JMP CONT
    SKIP:
    MOV AL/’.’
    INT 10H
    CONT:
    INC BX
    CMP BX/513
    JNZ PRINT
    INT 20H
    END START
     
  4. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,773
    تشکر شده:
    6,457
    امتیاز دستاورد:
    113
    پاسخ : اسمبلی یاد بگیریم

    عملگرهای بیتی

    عملگرهای بیتی مانند عملوندهای حسابی هستند با این تفاوت که روی بیت ها کار
    میکنند. این عملگرها عبارتند از : … AND/OR/XOR/SHR/SHL/RCL/RCR/ .

    عملگر AND : این اپراتور بیتهای دو عدد(متغیر) را با هم AND کرده و حاصل را در
    متغیر (یا ثبات ) سمت چپ قرار میدهد . اگر فرض کنیم که همیشه ۱ بودن بیت به
    معنای Trueو ۰و بودن آن به معنای False است ، AND همیشه در صورتیکه هر دوبیت
    مقایسه شونده ۱ باشند، حاصل ۱یا Trueا را بر میگرداند .
    جدول ارزشی AND :
    X | Y | X and Y |

    1 | 1 | 1 |
    1 | 0 | 0 |
    0 | 1 | 0 |
    0 | 0 | 0 |

    پس وقتی ما عملوند AND را با دو رجیستر بکار میبریم ، بصورتی که گفته شد بیتها
    با هم مقایسه شده و حاصل مقایسه در محل متناظر بیتها در ثبات سمت چپ قرار
    میگیرند . مثلا اگر دستور AND Ah/Dh را اجرا کنیم ، حالتی نظیر شکل زیر را داریم :
    AH : 01101010
    DH : 01111101

    AH :AH AND DH : 01101000

    به نتیجه بدست آمده توجه کنید .
    هر وقت که بخواهیم بیت های خاصی از یک رجیستر را ۰ کنیم ، یک عدد باینری که
    همه بیتهای آن ، بجز بیتهای مورد نظر ۱ هستند را در نظر گرفته با رجیستر مورد نظرAND
    میکنیم .مثلا اگر بخواهیم بیتهای دوم و سوم ثبات AX را صفر کنیم : AND AX/11111001b

    عملگر OR :
    این عملوند بیتهای دو عدد را با هم مقایسه کرده و اگر یکی از آن دو ۱ بود ، بیت
    متناظر در ثبات سمت چپ را ۱ میکند . مثلا با دستور OR AH/DH بیتهای AHبا DHا
    مقایسه شده و هر دو بیت متناظر که با هم ۰ بودند ، بیت تناظر در AHهم ۰ میشود
    AH : 01101010
    DH : 01111100

    AH : AH OR DH : 01111110

    هرگاه که بخواهیم بیت های خاصی از یک متغیر یا رجیستر را ۱ کنیم ، یک عدد
    باینری که همه بیتهای آن غیر از بیتهای مورد نظر ۰ هستند در نظر گرفته و با ثبات
    مورد نظر OR میکنیم . مثلا اگر بخواهیم دو بیت پائین AHرا ۱ا کنیم منویسیم : OR AH/00000011b

    عملگر : XOR
    عملوند XOR تنها در صورتی نتیجه ۱ میدهد که دو بیت مقایسه شونده غیرهم ارزش
    باشند . یعنی یکی ۱ و دیگری ۰ باشد .
    بعنوان مثال با اجرای XOR AH/DH این عملیات روی بیتها انجام میشود
    AH : 01101010
    DH : 01111100

    AH : AH XOR DH : 11101001

    وقتی بخواهیم یک مقدار ثبات را برابر صفر قرار بدهیم ، معمولا از آن را با خودش XOR
    میکنیم . مثلا XOR CX/CX محتوای ثبات CX را برابر ۰ قرار میدهد .

    عملگرهای SHRو SHLو :

    این عملگرها، بیتها را به راست و چپ شیفت ( انتقال ) میدهند .
    SHR Reg.nnum و SHL Reg.nnum
    .Reg اسم یک ثبات است مثلا AXو numو معلوم میکند که چند بیت باید به طرف
    راست یا چپ انتقال پیدا کند . مثلا SHR AX/6 بیتهای AXرا ۶ا واحد به راست
    انتقال داده و بیتهای چپ را با ۰ پر میکند . AX :10100010
    AX :SHR AX/4 : 00001010

    SHL
    هم عکس این عمل را انجام میدهد . یعنی بیتها را به چپ شیفت داده و از
    طرف راست با ۰ پر میکند . AX :10100010
    AX :SHR AX/4 : 00100000

    مثال : اگر بخواهیم که محتوای نیم ثبات CL را به نیم ثبات CH منتقل کنیم ،
    کافیت که CXرا ۸ا بیت به سمت چپ شیفت بدهیم . یعنی SHL CX/8

    CL CH | 10110100 | 00101101 |

    محتوای اولیه CX CX

    CL CH | 00101101 | 00000000 |

    محتوای CX بعد از SHL CX/8
    انتقال

    ادامه این بحث را در قسمت بعد انجام میدهیم .
     
  5. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,773
    تشکر شده:
    6,457
    امتیاز دستاورد:
    113
    پاسخ : اسمبلی یاد بگیریم

    در قسمت قبلی چند عملگر بیتی را دیدیم . در این قسمت هم این مبحص را دنبال
    میکنیم .
    عملگر Not : عملوند Not ارزش همه بیتهای یک بایت یا کلمه را برعکس میکند .
    یعنی تمام بیتهای ۱را ۰ا و تمام بیتهای ۰را ۱ا میکند . بعنوان مثال اگر AH حاوی
    مقدار ۱۰۱۰۱۱۰۱ باشد، بعد از اجرای Not Al ، محتوای AL بصورت ۰۱۰۱۰۰۱۰ خواهد
    بود.

    جدول ارزشی Not Not X X N
    F | T
    T | F

    عملگر Neg . این اپراتور معمولا با Not اشتباه میشود در صورتی که کمتر شباهتی بین
    آنها وجود دارد . Neg ارزش عددی یک عدد علامتدار را برعکس میکند . یعنی یک عدد
    منفی را مثبت میکند و برعکس . در اعداد علامتدار ( همانطور که بعدا هم خواهیم
    دید )، اولین بیت سمت چپ ( بیت هشتم ) بیت علامت است . ۱ بودن آن نشاندهنده
    منفی بودن و ۰ بودن آن نشان دهنده مثبت بودن است .
    عملگر Neg با عکس کردن بیت علامت ، ارزش عدد را عکس میکند .
    این عملوند را در مبحث اعداد علامتدار مفصلا میخوانیم .
    مثال : میخواهیم برنامه ای بنویسیم که تمام حروف کوچک یک عبارت را به حروف
    بزرگ تبدیل کند . از نظر مقدار عددی ، تفاوت حروف کوچک و بزرگ در اینست که
    بیت پنجم در حروف بزرگ برابر ۰ و در حروف کوچک ۱ است . مثلا کداسکی حرف a
    به باینری برابر ۰۱۱۰۰۰۰۱ و کد A برابر ۰۱۰۰۰۰۰۱ است . پس برنامه ای مینویسیم
    که تمام کاراکترهای رشته کاراکتری مورد نظر را خوانده و بیت پنچم آنها را ۰ کند
    . در قسمت قبلی دیدیم که برای ۰ کردن یک بیت ، یک عدد باینری که تمام بیتهای
    آن ۱ ، و بیت مورد نظر (برای ۰ کردن ) ۰ باشد را با عدد مورد نظر AND میکنیم .

    . MODEL SMALL
    . CODE
    ORG 100H
    START :
    JMP MAIN
    MSG DB ‘ this is an example/ ..$’
    MAIN :

    بدست آوردن آدرس رشته ; LEA BX/MSG LOOP :_

    قرار دادن کارکتر در AL ; MOV AL/[BX]
    آیا کاراکتر $ است ? ; CMP AL/’$’
    بله ، به MAIN برو ; _JZ END
    بیت پنجم را صفر کن ; AND [BX]/11011111B
    یکواحد به BX اضافه کن – کاراکتر بعدی ; INC BX JMP LOOP _;
    END :_

    قرار دادن آفست رشته در DX ; MOV DX/BX
    تابع ۹ برای نمایش رشته ; MOV AH/9
    قفه ۲۱h ; INT 21H
    پایان برنامه ; INT 20H END START

    معمولا برنامه هائی که پیغامهای خود را کد میکنند ( مثل ویروسها ) از این روش یا
    روشی مشابه برای Decode کردن پیغامها استفاده میکنند .

    مثال :
    بایت وضعیت صفحه کلید که مربوط به وضعیت کلید های کنترلی CapsLock/NumLock
    در بایوس های AT/PS2 در آدرس ۰۰۱۷h:0040h قرار دارد.
    بیتهای این بایت نشان میدهد که کدام کلید فعال است . ۱ بودن به معنی روشن بودن
    و ۰ به معنی خاموش بودن آن است . در مثال زیر بیت ششم برای کلید CapsLockرا ۱ا
    میکنیم تا Capslock روشن شود .
    .MODEL SMALL
    .CODE
    ORG 100h
    START:
    PUSH ES
    MOV AX/0040h
    MOV ES/AX
    MOV AL/ES:[17h]
    OR AL/32
    MOV BYTE PTR ES:[17h]/AL
    POP ES
    MOV AH/1
    INT