NASM打印输出时间 - 代码不输出任何内容

时间:2009-08-06 23:18:13

标签: assembly nasm

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

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 个答案:

答案 0 :(得分:6)

这里的第一个问题是您需要了解sys_time sys调用。在http://syscalls.kernelgrok.com/有一个方便的图表,它告诉你各种sys调用在寄存器中需要输入的内容。

sys_time是系统调用13,所以

mov eax,13

很好

然而,sys_time还需要在ebx中传递一个内存地址,它会写入实际时间。

快速的方法是在堆栈上分配一些空间(我们可以在堆栈上推送任何内容,sys_time值将覆盖它,为什么不将eax的值粘贴到它上面)。

push eax

然后将堆栈指针输入ebx

mov ebx, esp

现在进行系统调用

int 80h

现在我们可以将时间从堆栈中弹出(例如eax)

pop eax

现在eax包含当前的unix时间(即自1970年1月1日以来的秒数。)

为了避免将数字直接打印到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位可执行文件,因为它使用push和pop而您无法将32位寄存器压入64位堆栈。

nasm -f elf32 sys_time.asm
gcc -m32 sys-time.o -o sys-time

然后你应该

$ ./systime
1310190574

我已经在32位和64位linux上测试了这个,并设法编译上面的代码。如果您有任何问题,请告诉我。

为了回答你的问题看过nasm教程,我最近从Jeff Duntemann的“汇编语言一步一步,第三版”中学习。有关详细信息和示例章节,请参阅http://www.duntemann.com/assembly.html

答案 1 :(得分:3)

这是您转换为C的示例。您正在将时间指针复制到eax而不是eax到缓冲区。仍然这样做是行不通的,因为你想要一个char数组来写,而不是一个打印垃圾的原始整数。

#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);
}