Search code examples
timestampnasmmktimelocaltimectime

NASM: Getting the day of the week a different date


I have been tasked with writing a NASM program that gets the day of the week for the first day of the next month. As an example: If today is June 4, then the program should say something like:

July 1st is a Thursday.

I am using the mktime function as well as a few other time/date functions. Here is my code:

extern time
extern localtime
extern exit
extern printf
extern mktime
extern ctime

global main

section .data

sSun: db "Sunday", 0
sMon: db "Monday", 0
sTue: db "Tuesday", 0
sWed: db "Wednesday", 0
sThu: db "Thursday", 0
sFri: db "Friday", 0
sSat: db "Saturday", 0

format_1: db "%d", 10, 0
string: db "%s", 10, 0

section .bss
timestamp: resd 1
tmstruct: resd 1

section .text
main:
pusha

push dword 0       ; fetch the timestamp
call time
add esp, 4
mov [timestamp], eax

push timestamp
call localtime
add esp, 4

;change the localtime struct to indicate first day of next month.

;seconds, minutes, hours, day of month from 1.
mov [eax], dword 0
mov [eax + 4], dword 0
mov [eax + 8], dword 0
mov [eax + 12], dword 1
;get month # from 0, to ecx.
mov ecx, [eax + 16]
cmp ecx, 11
jne notDecember

;its december. Set date to January of next year.
mov [eax + 16], dword 0
mov ecx, [eax + 20]
inc ecx
mov [eax + 20], ecx
jmp convertDate

notDecember:

;its not december, just move up the month by 1.
mov ecx, [eax + 16]
inc ecx
mov [eax + 16], ecx

convertDate:
mov [tmstruct], eax

;make a timestamp
;push tmstruct <-- Wrong
push dword [tmstruct] ; <-- Right
call mktime
add esp, 4

;move timestamp
mov [timestamp], eax

;make a new tm struct
push timestamp
call localtime
add esp, 4

;now we have the correct date, check the day of the week
mov ecx, [eax + 24]
push ecx ;<--- preserve this value or c function calls will trash it!

;do a ctime call
;push dword eax <-- Wrong
push timestamp ; <-- Right
call ctime
add esp, 4
push dword eax
push string
call printf
add esp, 8

pop ecx ;<--- pop preserved value!
push dword ecx
call dayOfWeek

popa
call exit


dayOfWeek:

cmp [esp + 4], dword 0
je pSun

cmp [esp + 4], dword 1
je pMon

cmp [esp + 4], dword 2
je pTue

cmp [esp + 4], dword 3
je pWed

cmp [esp + 4], dword 4
je pThu

cmp [esp + 4], dword 5
je pFri

cmp [esp + 4], dword 6
je pSat

push dword esp
push format_1
call printf
add esp, 8
push format_1
jmp endDow



pSun:
push sSun
jmp endDow

pMon:
push sMon
jmp endDow

pTue:
push sTue
jmp endDow

pWed:
push sWed
jmp endDow

pThu:
push sThu
jmp endDow

pFri:
push sFri
jmp endDow

pSat:
push sSat
jmp endDow

endDow:
push string
call printf
add esp, 8
ret 4

Basically, i am told that "The mktime function ignores the specified contents of the structure members tm_wday and tm_yday..." (from localtime tm struct) "....and recomputes them from the other information in the broken-down time structure."

Seeing this as the case, my plan was to create a tm structure for the current time, and simply modify all its elements to point to the first second of the first day of the next month, then use mktime on that. However, you will see that the program outputs the "hijacked" struct as "Wed Dec 31 18:00:59 1969", but then i even print out the day of the week from THAT and i get sunday. What have i done to go so wrong here?


Solution

  • It seems i made a mistake in passing a value. Also, some of the c function calls seem to want to trash my values in the registers! Changes needed to run the code properly are commented with arrows.