Programming Contest #3 in ASM

Posts 12 of 2 · Page 1 of 1
Programming Contest #3 in ASM
Yup, did it in ASM as a practice application. It's good to learn in my opinion.

I don't know where the actual post is.. but.. The exercise was to display every Friday the 13th from year 1900 to year 2000.
I used the same logic as i used in the Challenge.

Bla bla bla, here goes the code. By the way, it might be a little (or a lot) messy but I'm still getting used to this shit.

Code:
.386
.model flat, stdcall
option casemap:none

include E:\masm32\include\windows.inc 
include E:\masm32\include\kernel32.inc 
include E:\masm32\include\masm32.inc 
include E:\masm32\include\user32.inc 
 
includelib E:\masm32\lib\user32.lib 
includelib E:\masm32\lib\kernel32.lib 
includelib E:\masm32\lib\masm32.lib 

GetMonthMax PROTO month:DWORD,year:DWORD

.data
hStd dd ?
bytesOut dd ?
monthsTOne dd 1,3,5,7,8,10,12,0
monthsTZero dd 4,6,9,11,0
currentDay dd ?
currentMonth dd ?
currentYear dd ?
total dd 0
number dd ?

.code

GetMonthMax PROC month:DWORD,year:DWORD

    MOV EDX, month

    ;Check if it is 31 days
    MOV EBX, offset monthsTOne
    TOne:
        CMP DWORD PTR [EBX], EDX
        JE endTOne
        ADD EBX, 4
        CMP DWORD PTR [EBX], 0
        JE continueTOne
        JMP TOne
    endTOne:
        MOV EAX, 31
        JMP endProc
    continueTOne:

    ;Check if it is 30 days
    MOV EBX, offset monthsTZero
    TZero:
        CMP DWORD PTR [EBX], EDX
        JE endTZero
        ADD EBX, 4
        CMP DWORD PTR [EBX], 0
        JE continueTZero
        JMP TZero
    endTZero:
        MOV EAX, 30
        JMP endProc
    continueTZero:

    ;Check if it is 28/29 days

    MOV EAX, year
    MOV ECX, 4
    DIV ECX

    CMP EDX, 0                  ;Check if Year % 4 Equals 0
    JNE endTFeb28

    MOV EAX, year
    MOV ECX, 100
    DIV ECX
    
    CMP EDX, 0                  ;Check if Year % 100 Equals 0
    JNE endTFeb
    
    MOV EAX, year
    MOV ECX, 400
    DIV ECX

    CMP EDX, 0                  ;Check if Year % 400 Equals 0
    JE endTFeb28
    
    endTFeb:
        MOV EAX, 29
        JMP endProc
    
    endTFeb28:
        MOV EAX, 28
    
    endProc:
    ret
    
GetMonthMax ENDP

START:

    ;push 1908
    ;push 2
    ;call GetMonthMax
    ;MOV monthDays, EAX

    MOV EDX, 5                  ;Starting day of 1900 year
    MOV ECX, 1900               ;Years - Starts at 1900, Ends at 2000
    yearsLoop:
        MOV EBX, 1              ;Months - Starts at 1, Ends at 12
        monthsLoop:
            infLoop:

                CMP EDX, 13
                JNE continueInfLoop
                push EAX                ;Uses EAX as a temporary store, saving the current value of it in the stack
                MOV EAX, total  
                INC EAX
                MOV total, EAX
                POP EAX                 ;Sets EAX value back from the stack

                continueInfLoop:
                ADD EDX, 7              ;Adds 7 days to the current day
                MOV currentDay, EDX     ;saves the current day
                MOV currentMonth, ECX   ;saves the current month
                MOV currentYear, EBX    ;saves the current year

                push ECX
                push EBX
                call GetMonthMax
                MOV ECX, currentMonth
                MOV EBX, currentYear

                MOV EDX, currentDay
                CMP EDX, EAX
                JL infLoop
                SUB EDX, EAX
            endInfLoop:

            INC EBX
            CMP EBX, 13
            JNE monthsLoop
        endMonthsLoop:
        
        INC ECX
        CMP ECX, 2001
        JNE yearsLoop
    endYearsLoop:

    

    ;OUTPUT
    push -11
    call GetStdHandle
    MOV hStd, EAX

    MOV ECX, 10
    MOV EAX, total
    MOV EBX, 0

    ;Convert from Decimal to ASCII
    convertNum:
        MOV EDX, 0
        DIV ECX
        push EDX
        INC EBX
        CMP EAX, 0
        JNE convertNum
    convertEnd:

    ;Stack stores the number now in the correct order
    ;EBX will have the number lengh

    MOV ECX, EBX

    MOV EDX, offset number
    saveNumber:
        POP EAX                 ;recover one number from the stack to EAX and then save it
        ADD EAX, 48             ;To convert it into the correct ASCII code
        MOV BYTE PTR [EDX], AL  ;Save the number to the byte pointed by EDX
        INC EDX                 ;Next byte to save the next number
        DEC EBX                 ;Counter--
        CMP EBX, 0
        JNE saveNumber
    saveEnd:

    ;Write to Console
    push 0
    push offset bytesOut
    push ECX
    push offset number
    push hStd
    call WriteConsole

    ;Exit Process
    push 0
    call ExitProcess

END START
I really iso tips to improve the code honestly.

Mainly this:
Code:
continueInfLoop:
                ADD EDX, 7              ;Adds 7 days to the current day
                MOV currentDay, EDX     ;saves the current day
                MOV currentMonth, ECX   ;saves the current month
                MOV currentYear, EBX    ;saves the current year

                push ECX
                push EBX
                call GetMonthMax
                MOV ECX, currentMonth
                MOV EBX, currentYear

                MOV EDX, currentDay
it was a "safe" way i found to save the data that was on the registers. But i believe there is a better way than saving to memory, asdfasdcasdfc... , load from memory (registers)
Posts 12 of 2 · Page 1 of 1

Post a Reply

Tags for this Thread

None

Need help?