这里的第一个问题是您需要了解sys_time sys调用。有一个便利的图表http://syscalls.kernelgrok.com/,告诉你各种sys调用需要作为寄存器中的输入。
SYS_TIME是系统调用13,所以
mov eax,13
好
然而SYS_TIME还要求EBX传递一个内存地址,它写的实际时间。
一个快速的方法是在堆栈上分配一些空间(我们可以在堆栈上推动任何东西,sys_time值会覆盖它,为什么不把它的值附加到堆栈上)。
push eax
然后喂堆栈指针到EBX
mov ebx, esp
现在使系统调用
int 80h
现在我们可以弹出时间从堆栈(进入如EAX)
pop eax
现在eax包含cur租用unix时间(即自1月1日1970年)的秒数
避免直接打印数字的trickyness到UNIX控制台我会欺骗,并提供通过GCC编译在NASM,并与C库链接,并使用printf的
一个完整的例子
[SECTION .data]
PrintNum db "%d",10,0 ;this is a c string so is null terminated
[SECTION .text]
extern printf
global main
main:
push ebp
mov ebp,esp
push ebx
push esi
push edi ; stuff before this for glibc compatibility
mov eax, 13
push eax
mov ebx, esp
int 0x80
pop eax
push eax ; push eax onto stack then the format string, then call printf to write eax to console, unwind stack pointer
push PrintNum
call printf
add esp,8
pop edi ; stuff after this for glibc compatibility
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
编译
nasm -f elf sys_time.asm
gcc sys-time.o -o sys-time
但如果你是在64位Linux,你可能需要做的(并有相关的multilib GCC和glibc)。您无法将此程序编译为本机64位可执行文件,因为它使用推送和弹出方式,并且无法将32位寄存器推送到64位堆栈。
nasm -f elf32 sys_time.asm
gcc -m32 sys-time.o -o sys-time
那么你应该得到
$ ./systime
1310190574
我在32位和64位Linux测试这一点,并设法编译上面的代码。如果您有任何问题,请告诉我。
为了回答你关于nasm教程的问题,我最近从Jeff Duntemann的“Assembly Language Step By Step,Third Edition”中学习。有关详细信息和示例章节,请参阅http://www.duntemann.com/assembly.html。
不要打垮自己。所有集会都很糟糕。 ;) – 2009-08-06 23:21:27
可能值得提及您正在使用的平台。 – 2009-08-06 23:57:20
我正在与64位Linux和NASM合作。 – kylc 2009-08-07 00:02:01