برنامه ای برای ثبت زمان یا به نوعی تایمر

MahmoodM30

مدیر <A href="http://forum.majidonline.com/forums/
برنامه ای برای ثبت زمان یا به نوعی تایمر در اسمبلی

این هم همون پروژه اسمبلی که توی تاپیک قبلی گفتم ممنون میشم راهنماییم کنین واقعا ضروری هست من خودمم دارم روش کار میکنم فقط چون تو کلاسا نبودم چیزی یاد نگرفتم پس تا جایی که میدونین کمک و راهنماییم کنین ممنون از همگی دوستان

- زمان بصورت دقیقه ، ثانیه و صدم ثانیه نمایش داده می شود و حداکثر آن 60 دقیقه می باشد.
- با فشار کلید s از صفحه کلید ،عبارت first time رنگی شده و زمان اول شروع به شمارش می کند. این زمان بصورت عناصر گرافیکی ( و نه عناصر عددی) نمایش داده می شود.برای مثال عدد 3 می تواند بصورت زیر یا هر نمایش غیر عددی متشکل از کاراکترها نمایش داده شود:

░░░░

░░░░

░░░░

- با فشار کلید t از صفحه کلید شمارشگر متوقف شده و زمان اول شروع به چشمک زدن میکند تا زمانی که کلید s فشار داده شده و شمارشگر مجددا به کار خود ادامه دهد.

- با فشار کلید 2 از صفحه کلید ، زمان اول کلا متوقف شده و عبارت first time بصورت عادی برگشته ، عبارت second time رنگی می شودو زمان دوم از ادامه زمان اول شروع به شمارش می کند ، برای مثال اگر زمان اول برابر 4:12:42 زمان دوم از 4:12:43 شروع به شمارش می کند.
دی این حالت با فشار کلید t زمان دوم متوقف و شروع به چشمک زدن میکند تا زمانی که کلید s مجددا فشار داده شود.
با زدن کلید e برنامه خاتمه پیدا میکند.

یه عکس هم گذاشتم
 

پیوست ها

  • untitled.JPG
    untitled.JPG
    10.5 کیلوبایت · بازدیدها: 9

the_king

مدیرکل انجمن
وقفه ساعت سیستم هر 18.2 ثانیه یکبار تیک می خوره، در نتیجه در محیط DOS و با سرویس های DOS ما میلی ثانیه
نداریم، در حد چند صدم ثانیه دقت خواهیم داشت، که به میلی ثانیه نمیرسه. به همین درستش اینه که بگیم
صدم ثانیه، نه میلی ثانیه. میشه یک 0 بهش اضافه کرد، اما عملا تغییر نمی کنه.

برای دریافت کردن زمان تا دقت میلی ثانیه یک تابع به اسم GetTime خواهیم ساخت که با استفاده از سرویس 2Ch در
وقفه 21h زمان را در حافظه time ذخیره کند. time یک آرایه 4 خانه ای است که به ترتیب صدم ثانیه، ثانیه، دقیقه و ساعت
فعلی کامپیوتر در آن ذخیره خواهد شد :
کد:
.DATA
    time    DB 0, 0, 0, 0

.CODE
GetTime:
    MOV     AH, 2Ch
    INT     21h
    MOV     time[0], DL
    MOV     time[1], DH
    MOV     time[2], CL
    MOV     time[3], CH
    RET
و هر زمانی که خواستیم با CALL فراخوانی اش می کنیم :
کد:
    CALL    GetTime

مقادیر time مستقیما برای نمایش مناسب نیستند، چون تایمر باید از 00:00:00.00 شروع کند، ولی time یک ساعت
است و زمان فعلی را در شبانه روز نشان می دهد.
ما باید تابعی بسازیم که یک زمان مبدا (زمان شروع کار تایمر) را از زمان فعلی کم کند تا مقادیر از زمان صفر
شروع شوند. ابتدا یک آرایه مشابه time با اسم baset معرفی می کنیم که زمان مبدا را نگهداری کند.
سپس تابع GetTimer را می سازیم تا زمان فعلی را از زمان مبدا کم کند تا مقدار تایمر بدست بیاید :
کد:
.DATA
    time    DB 0, 0, 0, 0
    baset    DB 0, 0, 0, 0
    msec    DB 0
    sec     DB 0
    min     DB 0
    hour    DB 0

GetTimer :
    CALL    GetTime
    MOV     BX, 0
    MOV     CX, 4
    MOV     AH, 0
    MOV     DL, 100
Subtract :
    MOV     AL, time[BX]
    SUB     AL, AH
    MOV     AH, 0
    SUB     AL, baset[BX]
    CMP     AL, DL
    JB      NextItem
    INC     AH
    ADD     AL, DL
NextItem :
    MOV     msec[BX], AL
    MOV     DL, 60
    INC     BX
    LOOP    Subtract
    RET

کم کردن مقادیر baset از time باید با دقت و مشابه تفریق کردن یکان و دهگان و صدگان ریاضی انجام شود،
مثلا زمانی که ثانیه time کوچکتر از ثانیه baset است، باید یک واحد از دقیقه time قرض گرفته شود و 60 واحد به ثانیه
time اضافه شود تا حاصل تفریق اشتباه نباشد. نتیجه محاسبه در حافظه msec و sec و min و hour ذخیره خواهد شد.

برای نمایش رقم ها هم به داده های تصویری شان نیاز داریم :
کد:
    digit0  DB " ### "
            DB "#   #"
            DB "#   #"
            DB "#   #"
            DB " ### "

    digit1  DB "  #  "
            DB " ##  "
            DB "  #  "
            DB "  #  "
            DB " ### "

    digit2  DB "#### "
            DB "    #"
            DB " ### "
            DB "#    "
            DB "#####"

    digit3  DB "#### "
            DB "    #"
            DB " ### "
            DB "    #"
            DB "#### "
.
.
.

و تابعی که یک رقم را روی صفحه نمایش نشان دهد :
کد:
ShowDigit :
    PUSH    DX
    MOV     BL, 25
    MUL     BL
    LEA     SI, digit0
    ADD     SI, AX
    MOV     CX, 5
LoopRow :
    PUSH    CX
    MOV     CX, 5
LoopCol :
    PUSH    CX
    PUSH    SI
    MOV     AH, 02h
    MOV     BH, 0
    INT     10h
    INC     DL
    MOV     AH, 09h
    MOV     BH, 0
    MOV     CX, 1
    MOV     BL, bgcolor
    POP     SI
    MOV     AL, [SI]
    PUSH    SI
    CMP     AL, 32
    JE      ShowChar
    MOV     AL, 32
    MOV     BL, fgcolor
ShowChar :
    INT     10h
    POP     SI
    INC     SI
    POP     CX
    Loop    LoopCol
    INC     DH
    SUB     DL, 5
    POP     CX
    DEC     CX
    JNZ     LoopRow
    POP     DX
    RET

و برای نمایش زمان msec و sec و min و hour به تابعی نیاز داریم که از تابع ShowDigit استفاده کند :
کد:
ShowTimer :
    MOV     DL, 7
    MOV     AL, hour
    MOV     AH, 0
    MOV     BL, 10
    DIV     BL
    PUSH    AX
    CALL    ShowDigit
    POP     AX
    ADD     DL, 6
    MOV     AL, AH
    CALL    ShowDigit
    ADD     DL, 6
    MOV     AL, 10
    CALL    ShowDigit
    MOV     AL, min
    MOV     AH, 0
    MOV     BL, 10
    DIV     BL
    PUSH    AX
    ADD     DL, 6
    CALL    ShowDigit
    POP     AX
    ADD     DL, 6
    MOV     AL, AH
    CALL    ShowDigit
    ADD     DL, 6
    MOV     AH, fgcolor
    CMP     AH, fgoff
    MOV     AL, 10
    JE      EvenSecond    
    MOV     AL, sec
    AND     AL, 1
    OR      AL, paused
    MOV     AL, 11
    JZ      EvenSecond
    MOV     AL, 10
EvenSecond :      
    CALL    ShowDigit
    MOV     AL, sec
    MOV     AH, 0
    MOV     BL, 10
    DIV     BL
    PUSH    AX
    ADD     DL, 6
    CALL    ShowDigit
    POP     AX
    ADD     DL, 6
    MOV     AL, AH
    CALL    ShowDigit
    ADD     DL, 6
    MOV     AL, 12
    CALL    ShowDigit
    MOV     AL, msec
    MOV     AH, 0
    MOV     BL, 10
    DIV     BL
    PUSH    AX
    ADD     DL, 6
    CALL    ShowDigit
    POP     AX
    ADD     DL, 6
    MOV     AL, AH
    CALL    ShowDigit
    RET

اگر بخواهیم تایمر توانایی pause کردن داشته باشد، به یک تابع برای جمع کردن مقادیر دو زمان نیاز داریم :
کد:
AddPauseTime :
    MOV     BX, 0
    MOV     CX, 4
    MOV     AH, 0
    MOV     DL, 100
AddTime :
    MOV     AL, msec[BX]
    ADD     AL, AH
    MOV     AH, 0
    ADD     AL, pauset[BX]    
    CMP     AL, DL
    JB      NextItem2
    SUB     AL, DL
    INC     AH
NextItem2 :
    MOV     msec[BX], AL
    MOV     DL, 60
    INC     BX
    LOOP    AddTime
    RET

attachment.php


برنامه کامل پیوستی بجز سر ساعت 23:59:59.99 که ساعت سیستم سر ریزی می کند در بقیه موارد اختلاف
ساعت ها رو درست محاسبه می کند، محدودیت تعداد ساعت هم ندارد، تا 24 ساعت را ذخیره می کند.
کد کامل asm به همراه فایل اجرایی exe ضمیمه این پست می باشد. Timer.zip
 

پیوست ها

  • Preview.gif
    Preview.gif
    4.8 کیلوبایت · بازدیدها: 39
  • Timer.zip
    2.3 کیلوبایت · بازدیدها: 41
آخرین ویرایش:

MahmoodM30

مدیر <A href="http://forum.majidonline.com/forums/
سلام واقعا ممنون از شما علی آقا نمیدونم با چه زبونی ازتون تشکر کنم مرسی ازتون

من هم از الان روش کار میکنم تا کامل یاد بگیرم اگه مشکلی بودم میتونم که بپرسم!؟
 

the_king

مدیرکل انجمن
سلام واقعا ممنون از شما علی آقا نمیدونم با چه زبونی ازتون تشکر کنم مرسی ازتون

من هم از الان روش کار میکنم تا کامل یاد بگیرم اگه مشکلی بودم میتونم که بپرسم!؟

صد البته، فقط توجه داشته باشید که تا حد امکان کد رو ساده تر نوشتم، به همین دلیل طول کد کمی طولانی تر
از حالت عادی است، مثلا اگر از دستورات rep stosb یا رجیستر های 32 بیتی مثل eax و edx استفاده می شد
کد پیچیده تر اما کوتاهتر می شد.
 

MahmoodM30

مدیر <A href="http://forum.majidonline.com/forums/
بله درست میفرمایید در هر حال واقعان ممنون از شما که کمکم کردین فعلا دارم روی کد ها کار میکنم تا چیزایی رو یاد بگیرم مرسی از شما
 

جدیدترین ارسال ها

بالا