Timestamp 吕震中本:把一周中的某一天换成不同的日期
我的任务是编写一个NASM程序,将一周中的某一天作为下个月的第一天。例如:如果今天是6月4日,那么节目应该说:Timestamp 吕震中本:把一周中的某一天换成不同的日期,timestamp,nasm,mktime,localtime,ctime,Timestamp,Nasm,Mktime,Localtime,Ctime,我的任务是编写一个NASM程序,将一周中的某一天作为下个月的第一天。例如:如果今天是6月4日,那么节目应该说: July 1st is a Thursday. 我正在使用mktime函数以及其他一些时间/日期函数。这是我的密码: extern time extern localtime extern exit extern printf extern mktime extern ctime global main section .data sSun: db "Sunday", 0 sM
July 1st is a Thursday.
我正在使用mktime函数以及其他一些时间/日期函数。这是我的密码:
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
外部时间
外部本地时间
外部出口
外部打印
外行mktime
外部时间
全球主要
第二节数据
主题:db"Sunday",0
sMon:db“星期一”,0
学生:db“星期二”,0
瑞典语:db“星期三”,0
sThu:db“星期四”,0
sFri:db“星期五”,0
sSat:db“周六”,0
格式_1:db“%d”,10,0
字符串:数据库“%s”,10,0
第2节bss
时间戳:resd1
结构:resd 1
第节.案文
主要内容:
普沙
推送dword 0;获取时间戳
通话时间
添加esp,4
mov[时间戳],eax
推送时间戳
呼叫本地时间
添加esp,4
;更改localtime结构以指示下个月的第一天。
;从1开始的秒、分钟、小时、月日。
mov[eax],dword 0
mov[eax+4],dword 0
mov[eax+8],dword 0
mov[eax+12],dword 1
;获取从0到ecx的月份。
mov ecx,[eax+16]
cmp ecx,11
十二月
;现在是十二月。把日期定在明年一月。
mov[eax+16],dword 0
mov ecx,[eax+20]
ecx公司
mov[eax+20],ecx
jmp转换日期
12月份:
;现在不是12月,只需将月份向上移动1。
mov ecx,[eax+16]
ecx公司
mov[eax+16],ecx
转换日期:
mov[tmstruct],eax
;做一个时间戳
;按下tmstruct好的,我取了C样本并修改它以满足您的需要:
extern printf, time, mktime, exit, localtime, scanf,strftime
global main
;~ int tm_sec Seconds [0,60].
;~ int tm_min Minutes [0,59].
;~ int tm_hour Hour [0,23].
;~ int tm_mday Day of month [1,31].
;~ int tm_mon Month of year [0,11].
;~ int tm_year Years since 1900.
;~ int tm_wday Day of week [0,6] (Sunday =0).
;~ int tm_yday Day of year [0,365].
;~ int tm_isdst Daylight Savings flag.
%define tm_sec 0
%define tm_min 4
%define tm_hour 8
%define tm_mday 12
%define tm_mon 16
%define tm_year 20
%define tm_wday 24
%define tm_yday 28
%define tm_isdst 32
section .bss
timeinfo resd 1
rawtime resd 1
lpszBuffer resb 80
section .data
fmtdate db "%B %d %Y", 0
Sun db "Sunday", 0
Mon db "Monday", 0
Tue db "Tuesday", 0
Wed db "Wednsday", 0
Thu db "Thursday", 0
Fri db "Friday", 0
Sat db "Saturday", 0
WeekDay dd Sun, Mon, Tue, Wed, Thu, Fri, Sat
szThatDay db "%s is a %s", 10, 0
section .text
main:
;~ Get todays date
push rawtime
call time
add esp, 4 * 1
push rawtime
call localtime
add esp, 4 * 1
mov dword [timeinfo], eax
;~ Get current month and add one
mov edx, dword [eax + tm_mon]
inc edx
;~ move updated month back to structure
mov dword [eax + tm_mon], edx
;~ set day to the first
mov dword [eax + tm_mday], 1
push dword [timeinfo]
call mktime
add esp, 4 * 1
push dword [timeinfo]
push fmtdate
push 80
push lpszBuffer
call strftime
add esp, 4 * 4
mov eax, dword [timeinfo]
mov eax, dword [eax + tm_wday]
mov ecx, dword [WeekDay + 4 * eax]
push ecx
push lpszBuffer
push szThatDay
call printf
add esp, 4 * 3
call exit
然后为了测试,我显示了当前日期并运行了程序,然后显示了下个月1号的星期几。然后,我更改了系统时钟并再次运行测试2次。测试也在Windows下运行
我似乎在传递值时犯了一个错误。另外,一些c函数调用似乎想在寄存器中丢弃我的值!正确运行代码所需的更改用箭头注释。我看到了您的答案。我只是想尝试并确保我理解这一点,也许在我标记它之前用它来修改我的原始代码。谢谢你的回复!:)你怎么可能增加月数,即使是12月,这仍然有效?你没有处理逐年递增的问题,但我清楚地看到你12月份的产出中有一个例子,它是有效的!在C库的魔域中,月份是以零为基础的,因此在调用time
和localtime
后,将10月(当前月份)返回为9,加上1:10,这是11月对吗?这将使12月11日增加一个,月份是12,C库中的代码知道当前年份,并且知道没有12个月,所以是明年的1月(IMO它是这样工作的,因为我没有看过mktime
)Gunner的代码。。。我试图修改我的代码,以采用与您类似的方法。我真的很想了解这一点。。。虽然你的代码工作完美无瑕,但我需要学会用我自己的方式编写。在输出到控制台之前,我已经使用了我的大部分代码,并做出了与您相同的语句,在控制台中我仍然使用dayOfWeek方法。不知何故,现在它给出了segfault,即使我平衡了堆栈,也不认为我访问了坏的内存位置。我可以通过您的电子邮件与您联系吗?或者如果我更新我的帖子以显示当前代码,您可以在这里帮助我吗?我发现了我的问题。似乎有些c函数会破坏我的寄存器。不知道为什么来自最常用语言之一的代码会做这样的事情!阅读此文:请注意有关Intel ABIYes的部分。是的,我正在艰难地学习某些值被协议破坏,而其他值则被保留。在NASM中,值与链接的值不同。它们包括EBX、ESI、EDI和另一个我忘记的寄存器。当然,ESP总是被保留的!;)