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

آموزش اسمبلی(13)

شروع موضوع توسط hector2141 ‏15/10/12 در انجمن Assembly

  1. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,323
    تشکر شده:
    2,698
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    [​IMG]
    در این قسمت یک تمرین جدید انجام داده و بوسیله آن تجربیات خودمان را افزایش میدهیم . این تمرین اولین برنامه ما هست که عملیات سطح پائین سیستم ، یعنی دسترسی به دیسک ، را انجام میدهد .


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

    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
    و در نهایت فراخوانی اینتراپت:
    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 /( …DRIVENUMBER)
    PUSH AX ; SAVE AX
    MOV AX/DS
    MOV ES/AX
    POP AX
    LEABX/BUF
    INT 13H

    MOV BX/1
    MOV AH/0EH ; WRITE CHAR.
    PRINT:
    MOV AL/BUF[BX]
    CMPAL/32
    JB SKIP
    INT 10H
    JMP CONT
    SKIP:
    MOV AL/’.’
    INT 10H
    CONT:
    INC BX
    CMP BX/513
    JNZ PRINT
    INT 20H
    END START



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