2009-08-06 83 views
1

我刚刚开始使用ASM(NASM),并且需要以下代码片段的帮助。我没有得到任何错误/警告,它只是不输出任何内容。我期待的是让它得到时间(13),然后打印出来(4),然后退出(1)。另外,有没有人知道一些好的(最好是NASM特定的)ASM教程?NASM打印出时间码 - 不输出任何东西

section .bss 
    time: resb 255 

section .text 
    global _start 

_start: 
    mov eax, 13 
    int 0x80 
    mov eax, time 

    mov edx, 255 
    mov ecx, time 
    mov ebx, 1 
    mov eax, 4 
    int 0x80 

    mov eax, 1 
    int 0x80 
+2

不要打垮自己。所有集会都很糟糕。 ;) – 2009-08-06 23:21:27

+0

可能值得提及您正在使用的平台。 – 2009-08-06 23:57:20

+0

我正在与64位Linux和NASM合作。 – kylc 2009-08-07 00:02:01

回答

3

这是您的示例翻译为C.您正在将指针复制到eax而不是eax到缓冲区。仍然不会工作,因为你想要一个字符数组进行写入,而不是一个会打印垃圾的原始整数。

#include <stdlib.h> 

char b[255]; 

int 
main() 
{ 
     /* You wanted to do this which doesn't work 
     * because write wont take int* but char arrays 
     * *(int*)b=time(NULL); 
     */ 

     /* Instead you did */ 
     time(NULL); 
     b; 
     write(1, b, 255); 
     exit(1); 
} 
6

这里的第一个问题是您需要了解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