نوشتن تقويم ( اسمبلي )

hobab1987

Member
چه قشنگ شد!
يك مشكلي باز پيش اومد روزهاي جمعه را با اينكه رنگش را تعيين كرديم اما مشكي چاپ شد!
مقايسته روز با 5 را هم اضافه كردم كه مربوط به روز جمعه و پايان ماه قمريست.
=========
با اضافه كردن مقايسته جديد با 5 روز هاي جمعه چاپ شد اما چند تا از روزهاي معمولي چاپ نشده اند!
==========
اینکار را هم می توان انجام داد، اما به نظرتان ترتیب نمایشی روز ها با اضافه کردن متن مناسبت بهم نمی خورد؟
اصولا مناسبت ها را پایین تقویم و بطور جداگانه می نویسند، نه میان اعداد روز های تقویم
.
خوب قبلش موقعيت متن رو مشخص مي كنم.
راه بهتري وجود دارد؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
چه قشنگ شد!
يك مشكلي باز پيش اومد روزهاي جمعه را با اينكه رنگش را تعيين كرديم اما مشكي چاپ شد!
مقايسته روز با 5 را هم اضافه كردم كه مربوط به روز جمعه و پايان ماه قمريست.
=========
با اضافه كردن مقايسته جديد با 5 روز هاي جمعه چاپ شد اما چند تا از روزهاي معمولي چاپ نشده اند!
==========
لطفا کدتان را ضمیمه کنید را بتوانم اشکال را پیدا کنم. در کدتان برای dmap های 3 و 4 شرطی ننوشته بودید؟

خوب قبلش موقعيت متن رو مشخص مي كنم.
راه بهتري وجود دارد؟
راه های پیچیده بله، ولی راه ساده تر این است که متن کل مناسبت ها را یکجا و با یک سرویس 9 از وقفه 21h
نمایش دهید، یعنی یک رشته با DB بسازید که چند سطر باشد و در هر سطر روز و مناسبت آن روز را نمایش دهید،
رشته بایستی به $ ختم شود. کد زیر شمای کلی نحوه ایجاد کردن آن رشته است :
کد:
dtxt	DB "01 Farvardin    your text for day 01", 13, 10
	DB "02 Farvardin    your text for day 02", 13, 10
	DB "03 Farvardin    your text for day 07", 13, 10
	DB "24 Farvardin    your text for day 24", 13, 10
	.
	.
	.
	DB "29 Khordad    your text for day 29", 13, 10, "$"

و در انتهای کد برنامه تان و بعد از نمایش جدول تقویم نمایش اش می دهید :
کد:
MOV	AH, 9
LEA	DX, dtxt
INT	21h
 

hobab1987

Member
لطفا کدتان را ضمیمه کنید را بتوانم اشکال را پیدا کنم. در کدتان برای dmap های 3 و 4 شرطی ننوشته بودید؟
براي dmap 3 اضافه شد 1error داد!!!
شرط براي 3 را در gday گذاشتم .
گفتم error ها برطرف شد، بقيه كدها را اضافه كنيم.
راستي day را در quit ، 0 كردم.
کد:
stacksg segment stack 'stack'
stacksg ends
datasg segment 'data'
    day        DB 00H
    pmonth    DB 01H
    pday    DB 01H
    gmonth    DB 03H
    gday    DB 21H
    imonth    DB 03H
    iday    DB 23H
    dmap    DB 1, 1, 1, 1, 0, 0, 5, 0, 0, 0, 3, 1, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0
            DB 0, 0, 0, 2, 4, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0
            DB 2, 0, 0, 4, 0, 0, 2, 2, 0, 3, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0     
datasg ends
codsg segment 'code'
assume ss:stacksg, ds:datasg, cs:codsg
main proc 
    MOV        AX, datasg
    MOV        DS, AX    
[COLOR=Red]loop_pday:[/COLOR]
    MOV         AL, pday
    MOV         BL, day
    MOV         BH, 0
    CMP         dmap[BX], 0
    JE       color3
    CMP         dmap[BX], 1
    JE         color1
    CMP         dmap[BX], 2
    JE         color2
    CMP         dmap[BX], 5
    JE         color2
[COLOR=Red]pday_label:[/COLOR]
    CALL print_al_color_bh
    MOV         AH, 2
    MOV         DL, 32
    int         21h
    INC         pday        
    INC         day
    CMP         pday, 32
    JNE    loop_pday
    CMP         day, 93
    JE    loop_quit
    INC         pmonth
    MOV         pday, 1
    JMP    loop_pday
color1:
    MOV         BH, 0Eh
    JMP         pday_label
color2:
    MOV         BH, 0Ch    
    JMP         pday_label
color3:
    MOV      BH, 07h
    JMP      pday_label
[COLOR=RoyalBlue]gday_label:
    MOV         AL, gday
    MOV         BL, day
    MOV         BH, 0
    CALL print_al
    MOV         AH, 2
    MOV         DL, 32
    INT         21h
    CMP         day[BX], 3
    JE         label1
    INC         gday
    INC         day
    CMP         day, 93
    JE         loop_quit
    JMP    loop_gday
label1:
    MOV         gday, 1
    INC         gmonth
    JMP         gday_label      [/COLOR]       
loop_quit:
    [COLOR=YellowGreen]MOV         day, 0[/COLOR]
    MOV         AH, 08h
    INT         21H
    MOV         AX, 4c00h
    INT         21H 
print_al:
    MOV         AH, 0
    MOV         DL, 10
    DIV         DL
    ADD         AX, 3030h
    PUSH     AX
    MOV         DL, AL
    MOV         AH, 2
    INT         21H
    POP         DX
    MOV         DL, DH
    INT         21H
    RET    
print_al_color_bh:
    PUSH     AX
    MOV      AX, 0920h
    MOV      BL, BH
    MOV      BH, 0
    MOV      CX, 2
    INT      10h
    POP      AX
    MOV      BH, BL
    MOV      AH, 0
    MOV      DL, 10
    DIV      DL
    ADD      AX, 3030h
    PUSH     AX
    MOV      AH, 2
    MOV      DL, AL
    INT      21H
    POP      AX
    MOV      DL, AH
    MOV      AH, 2
    INT      21H
    MOV      DL, 32
    INT      21H
    RET
main endp
codsg ends
end main
 
آخرین ویرایش:

the_king

مدیرکل انجمن
منطق کد رو ریختین بهم، اصلا label ای با عنوان loop_gday در کدتون ندارید که دستور پرش رو دادید :
کد:
    JMP         loop_gday

در ضمن زمانی که حلقه pday در loop_pday تموم شد، برنامه هم خاتمه پیدا می کنه، این کد بخش gday_label
اصلا فراخوانی نمیشه که اجرا بشه.

متغیر day فقط و فقط یک بایته، آرایه نیست که کد زیر رو برایش نوشتید، کلا اشتباهه :
کد:
    CMP         day[BX], 3

dmap با مقدار 3 فرقی با بقیه حالات نداره که خطا بده، احتمالا جای دیگری اشتباه داشته اید.

print_al رو برای چه منظوری نگه داشتید؟ دیگه نیازی بهش ندارید، از print_al_color_bh استفاده کنید.
 

hobab1987

Member
خوب دستوراتم را كه مثل قبل اضافه كردم چرا منطقش ايراد دارد؟!
حلقه اول وقتي تمام شد به جاي QUIT پرش دادم به LOOP2 كه دوباره بايد بعد از اتمام اين حلقه پرش كنم به يك LOOP3 مثل همين كه تكراريه و باز بايد بنويسم ، راه بهتري هست؟ لطفا راهنمايي كنيد.
كد اصلاح شده همراه 1 ERROR
کد:
stacksg segment stack 'stack'
stacksg ends
datasg segment 'data'
    day        DB 00H
    pmonth    DB 01H
    pday    DB 01H
    gmonth    DB 03H
    gday    DB 21H
    imonth    DB 03H
    iday    DB 23H
    dmap    DB 1, 1, 1, 1, 0, 0, 5, 0, 0, 0, 3, 1, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0
            DB 0, 0, 0, 2, 4, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0
            DB 2, 0, 0, 4, 0, 0, 2, 2, 0, 3, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0     
datasg ends
codsg segment 'code'
assume ss:stacksg, ds:datasg, cs:codsg
main proc 
    MOV        AX, datasg
    MOV        DS, AX    
loop_pday:
    MOV         AL, pday
    MOV         BL, day
    MOV         BH, 0
    CMP         dmap[BX], 0
    JE       color3
    CMP         dmap[BX], 1
    JE         color1
    CMP         dmap[BX], 2
    JE         color2
    CMP         dmap[BX], 5
    JE         color2
pday_label:
    CALL print_al_color_bh
    MOV         AH, 2
    MOV         DL, 32
    int         21h
    INC         pday        
    INC         day
    CMP         pday, 32
    JNE    loop_pday
    [COLOR=Red]CMP         day, 93
    JE         loop2[/COLOR]
    INC         pmonth
    MOV         pday, 1
    JMP    loop_pday
color1:
    MOV         BH, 0Eh
    JMP         pday_label
color2:
    MOV         BH, 0Ch    
    JMP         pday_label
color3:
    MOV      BH, 07h
    JMP      pday_label
[COLOR=Red]loop2:
    MOV         day, 0
    MOV         AH, 2
    MOV         DL, 13
    INT         21h
    MOV         DL, 10
    INT         21h[/COLOR]
[SIZE=2] gday_label:
    MOV         AL, gday
    MOV         BL, day
    MOV         BH, 0
   [/SIZE][SIZE=2][COLOR=Red] CALL print_al_color_bh:[/COLOR][/SIZE][SIZE=2]
    MOV         AH, 2
    MOV         DL, 32
    INT         21h
   [/SIZE][SIZE=2][COLOR=Red] CMP         dmap[BX], 3[/COLOR][/SIZE][SIZE=2]
    JE         label1
    INC         gday
    INC         day
    CMP         day, 93
    JE         loop_quit
   [/SIZE][SIZE=2][COLOR=Red] JMP         gday_label[/COLOR][/SIZE][SIZE=2]
[/SIZE] [SIZE=2][COLOR=RoyalBlue]label1:[/COLOR][/SIZE][SIZE=2]
    MOV         gday, 1
    INC         gmonth
    JMP         gday_label   [/SIZE]          
loop_quit:
    MOV         AH, 08h
    INT         21H
    MOV         AX, 4c00h
    INT         21H 
print_al_color_bh:
    PUSH     AX
    MOV      AX, 0920h
    MOV      BL, BH
    MOV      BH, 0
    MOV      CX, 2
    INT      10h
    POP      AX
    MOV      BH, BL
    MOV      AH, 0
    MOV      DL, 10
    DIV      DL
    ADD      AX, 3030h
    PUSH     AX
    MOV      AH, 2
    MOV      DL, AL
    INT      21H
    POP      AX
    MOV      DL, AH
    MOV      AH, 2
    INT      21H
    MOV      DL, 32
    INT      21H
    RET
main endp
codsg ends
end main
 

the_king

مدیرکل انجمن
خوب دستوراتم را كه مثل قبل اضافه كردم چرا منطقش ايراد دارد؟!
حلقه اول وقتي تمام شد به جاي QUIT پرش دادم به LOOP2 كه دوباره بايد بعد از اتمام اين حلقه پرش كنم به يك LOOP3 مثل همين كه تكراريه و باز بايد بنويسم ، راه بهتري هست؟ لطفا راهنمايي كنيد.
منطق اش از این نظر اشکال داره که دیگه یک جدول سه تقویمی نیست، بلکه سه جدول جداست، در ضمن
روز های تعطیل رو در جدول gday مشخص نکردید.
پیشنهاد می کنم که سه تقویم با هم ترکیب شوند، طول کد هم خیلی کمتر می شود. می توانید از رنگ های
متنوع برای تفکیک بهتر روز های قمری و میلادی از شمسی استفاده کنید.

این کد چند تا اشکال داره، اول اینکه کاربرد : برای تعریف کردن label است، در دستور CALL نبایستی
: قرار می دادید :
کد:
    MOV         BL, day
    MOV         BH, 0
    CALL print_al_color_bh[B]:[/B]

در ضمن وقتی print_al_color_bh را فراخوانی می کنید، BH قراره رنگ متن باشه، شما روی مشکی (0)
تنظیم اش کردید که اصلا دیده نمیشه.

همچنین شما بایستی مقدار BX را از زمانی که مقدار دهی می کنید تا زمانی که مقایسه اش می کنید حفظ نمایید،
مقدار BX را جایی روی day تنظیم کردید که یک خط پایین تر با فراخوانی print_al_color_bh تخریب می شود،
بدیهی است که مقایسه چند سطر پایین تر هم درست انجام نخواهد شد :
کد:
    CMP         dmap[BX], 3
بهتر است که BX را همان جایی روی day تنظیم کنید که قرار است از آن استفاده شود.

این کد هم اشکال دارد، چون اگر شرط آخرین روز ماه gday برقرار باشد، به label1 پرش می کند و مقدار day را
افزایش نمی دهد، در حالی که افزایش day بایستی در هر شرایطی انجام شود :
کد:
    CMP         dmap[BX], 3
    JE         label1
    INC         gday
[B]    INC         day[/B]
.
.
.
 label1:
    MOV         gday, 1
    INC         gmonth
    JMP         gday_label
 

the_king

مدیرکل انجمن
من این شیوه را پیشنهاد می کنم، در ضمن در کدتان gday و iday را بصورت هگزادسیمال نوشته اید که کلا اعداد
اشتباهی است. تقویم dmap و print_al_color_bh را هم ویرایش کردم. دقت کنید که day اکنون DW است نه DB.

کد:
.MODEL      SMALL
.STACK
.DATA
    day     DW 0
    pmonth  DB 1
    pday    DB 1
    gmonth  DB 3
    gday    DB 21
    imonth  DB 3
    iday    DB 23
    dmap    DB 1, 1, 1, 1, 0, 0, 5
            DB 0, 0, 0, 2, 1, 1, 1
            DB 0, 0, 0, 0, 0, 0, 1
            DB 0, 0, 0, 0, 0, 0, 1
            DB 0, 0, 0
            DB          0, 0, 0, 1
            DB 4, 0, 0, 0, 0, 2, 1
            DB 0, 0, 0, 0, 0, 0, 1
            DB 0, 0, 0, 0, 0, 0, 1
            DB 0, 0, 0, 0, 0, 0
            DB                   1
            DB 0, 0, 4, 0, 0, 1, 1
            DB 0, 2, 0, 0, 0, 1, 1
            DB 0, 0, 0, 0, 0, 0, 1
            DB 0, 0, 0, 0, 0, 0, 1
            DB 0, 0
    ctitle  DB " Saturday    Sunday     Monday    Tuesday   Wednesday   Thursday    Friday"
            DB 13, 10, "$"
.CODE
.STARTUP
    MOV     AX, 3
    INT     10h
    MOV     AX, 0920h
    MOV     BX, 0030h
    MOV     CX, 76
    INT     10h
    MOV     AH, 9
    LEA     DX, ctitle
    INT     21h
loop_day:    
    MOV     BH, 1Fh
    MOV     SI, day
    TEST    dmap[SI], 1
    JZ      print_pday
    MOV     BH, 4Fh
print_pday:
    MOV     AL, pday
    CALL    print_al_color_bh
    MOV     BH, 1Eh
    TEST    dmap[SI], 1
    JZ      print_gday
    MOV     BH, 4Eh
print_gday:
    MOV     AL, gday
    CALL    print_al_color_bh
    MOV     BH, 17h
    TEST    dmap[SI], 1
    JZ      print_iday
    MOV     BH, 47h
print_iday:
    MOV     AL, iday
    CALL    print_al_color_bh
    INC     iday
    TEST    dmap[SI], 4
    JE      next_iday
    MOV     iday, 1
next_iday:
    INC     gday
    TEST    dmap[SI], 2
    JE      next_gday
    MOV     gday, 1
next_gday:
    MOV     AH, 2
    MOV     DL, 32
    INT     21h
    MOV     AX, 0920h
    MOV     BX, 0007h
    MOV     CX, 1
    INT     10h
    MOV     AH, 2
    MOV     DL, 32
    INT     21h
    INC     day
    MOV     AX, day
    DEC     AX
    MOV     DL, 7
    DIV     DL
    CMP     AH, 6
    JNE     next_day
    MOV     AH, 2
    MOV     DL, 13
    INT     21h
    MOV     DL, 10
    INT     21h
next_day:
    INC     pday
    CMP     pday, 32
    JNE     loop_day
    INC     pmonth
    MOV     pday, 1
    CMP     day, 93
    JNE     loop_day
    MOV     AH, 08h
    INT     21H
    MOV     AX, 4C00h
    INT     21H     
print_al_color_bh:
    PUSH    AX
    MOV     AX, 0920h
    MOV     BL, BH
    MOV     BH, 0
    MOV     CX, 4
    INT     10h
    MOV     AH, 2
    MOV     DL, 32
    INT     21H
    POP     AX
    MOV     BH, BL
    MOV     AH, 0
    MOV     DL, 10
    DIV     DL
    ADD     AX, 3030h
    PUSH    AX
    MOV     AH, 2
    MOV     DL, AL
    INT     21H
    POP     AX
    MOV     DL, AH
    MOV     AH, 2
    INT     21H
    RET
END

کد کامل برنامه به همراه فایل اجرایی exe ضمیمه این پست می باشد.
 

پیوست ها

  • Calendar Assembly.zip
    1.1 کیلوبایت · بازدیدها: 2

hobab1987

Member
خيلي عالي بسيار زيبا!!!

منطق اش از این نظر اشکال داره که دیگه یک جدول سه تقویمی نیست، بلکه سه جدول جداست،
بله، خوب گفتن جدا بايد بنويسيد!!! يك قسمت اختياري برامون گذاشتن كه روز شمسي را به روزهاي ديگر مثل ميلادي تبديل كنيم ، شايد به اين خاطر گفتن جدا بنويسيد وگرنه اينجوري كه عاليه!
 

hobab1987

Member
چند سوال:
1)اين قرمز ها چه كار ميكنه؟


کد:
[COLOR=Red]MOV     AX, 3
INT     10h[/COLOR]
MOV     AX, 0920h
MOV     BX, 0030h
[COLOR=Red] MOV     CX, 76[/COLOR]
INT     10h
کد:
 MOV     AH, 2
    MOV     DL, [COLOR=Red]32[/COLOR]
    INT     21h


کد:
[COLOR=Red]INC     day
    MOV     AX, day
    DEC     AX
    MOV     DL, 7
    DIV     DL
    CMP     AH, 6
    JNE     next_day[/COLOR]
2) در مورد رنگ ها اينجوري برداشت كردم:
اينجا اول رنگ را پيش فرض انتخاب كرديد بعد اگر شرط برقرار شد با jz يا je پرش مي كند و دستور خط بعد اجرا نمي شود.
[FONT=&quot]لطفا توضيح دهيد.[/FONT]
کد:
loop_day:    
    MOV     BH, 1Fh
    MOV     SI, day
    TEST    dmap[SI], 1
    JZ      print_pday
    MOV     BH, 4Fh

يك خواهش داشتم
[FONT=&quot]مي شود كد برنامه را با [/FONT][FONT=&quot]
tasm,tlink
اجرا كنيد پيوست كنيد(با مشكل مواجه شدم)
[/FONT]
 
آخرین ویرایش:

the_king

مدیرکل انجمن
این دو سطر که همانند CLS است، مد متنی رو مجددا تنظیم می کنه و در نتیجه صفحه مانیتور پاک میشه :
کد:
MOV     AX, 3
INT     10h

برای آنکه رنگ سطر اول (عنوان روز های هفته) را با رنگ 30h رنگ کنیم، از سرویس 9 وقفه 10h استفاده میشه.
AH شماره سرویس است که 09h میشه، AL کد کاراکتری است که نمایش می دهیم که من فاصله فرض اش کردم،
یعنی 32 یا به عبارتی 20h . مجموع AL و AH هم که میشه AX برابر با 0920h
BH شماره صفحه است که 00 است، BL هم کد رنگ است که 30h در نظر گرفتم، پس BX می شود 0030h
CX تعداد کاراکتر ها است، مجموع کاراکتر های عنوان روز های هفته هم 76 کاراکتر بود.
کد:
MOV     AX, 0920h
MOV     BX, 0030h
 MOV     CX, 76
INT     10h

این هم که مشخصه، یک کاراکتر فاصله (کد 32) را نمایش می دهد :
کد:
 MOV     AH, 2
    MOV     DL, 32
    INT     21h

برای آنکه روز های هر هفته در یک سطر متفاوت چاپ شوند، بایستی آنها را به دسته های 7 روزه تقسیم کنیم،
اگر day را از 0 شروع کنیم و باقیمانده تقسیم آن بر 7 برابر 6 باشد، آنروز آخرین روز هفته است :
این سطر ربطی به این مساله ندارد، به هر حال هر بار day یک واحد افزایش داده می شود :
کد:
INC     day

مقدار day را در AX می خوانیم، ولی اکنون مقدار day مربوط به فردا است، چون یک واحد افزایش یافته،
پس مقدارش را کاهش می دهیم :
کد:
    MOV     AX, day
    DEC     AX

AX را بر 7 تقسیم می کنیم :
کد:
    MOV     DL, 7
    DIV     DL

اگر AH برابر 6 بود (باقیمانده تقسیم) پس آخرین روز هفته است، وگرنه به next_day پرش می کند :
کد:
    CMP     AH, 6
    JNE     next_day

بله، رنگ پیشفرض را انتخاب می کنم، اگر مطابقت داشت که پرش برای نمایش صورت می گیرد، و در غیر اینصورت
ابتدا رنگ تعویض می شود.

کد را مطابق با Tasm 5.3 تغییر دادم که پیوست این پست می باشد.
 

پیوست ها

  • g.zip
    1.8 کیلوبایت · بازدیدها: 3

hobab1987

Member
مگر قرارمون نبود كه وقتي آخر ماه شمسي يا قمري يا ميلادي شد اونوقت مقدارشان را دوباره يك كنيم پس چرا اينجا برعكس انجام داديد؟
کد:
print_iday:
    MOV     AL, iday
    CALL    print_al_color_bh
    INC     iday
    TEST    dmap[SI], 4
    JE      next_iday
    MOV     iday, 1
next_iday:
    INC     gday
    TEST    dmap[SI], 2
    JE      next_gday
    MOV     gday, 1
يا وقتي روز تعطيل بود backcolor قرمز باشد پس چرا اينجا جابجا نوشته شده؟ 1F پيشفرض را آبي قرار داديد كه اگر روز 1 شد با اين رنگ چاپ شود!!!!
کد:
loop_day:    
    MOV     BH, 1Fh
    MOV     SI, day
    TEST    dmap[SI], 1
    JZ      print_pday
    MOV     BH, 4Fh
print_pday:
    MOV     AL, pday
    CALL    print_al_color_bh
 

the_king

مدیرکل انجمن
مگر قرارمون نبود كه وقتي آخر ماه شمسي يا قمري يا ميلادي شد اونوقت مقدارشان را دوباره يك كنيم پس چرا اينجا برعكس انجام داديد؟
يا وقتي روز تعطيل بود backcolor قرمز باشد پس چرا اينجا جابجا نوشته شده؟ 1f پيشفرض را آبي قرار داديد كه اگر روز 1 شد با اين رنگ چاپ شود!!!!
لازمه که توضیحاتی که قبلا در مورد دستور test و مقایسه بیتی دادم را مجددا با دقت مطالعه کنید.
در مقایسه بیتی با test نتیجه همانند دستور and است، je یا jz یعنی بیت های مقایسه شونده صفر باشند،
یعنی درست برعکس آنچه انتظار دارید.
 

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

بالا