Question

I'm just getting started with ASM (NASM), and need some help with the following snippet. I get no errors/warnings, it just doesn't output anything. What I was expecting was for it to get the time (13), then print that out (4), then exit (1). Also, does anyone know of some good (preferably NASM specific) ASM tutorials?

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
Was it helpful?

Solution

This is your example translated to C. You are copying the pointer to time to eax instead of eax to the buffer. Still that wouldn't work because you want a char array for write and not a raw integer which will print garbage.

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

OTHER TIPS

The first problem here is that you need to understand the sys_time sys call. There is a handy chart at http://syscalls.kernelgrok.com/ that tells you what the various sys calls require as input in registers.

sys_time is system call 13, so

mov eax,13

is good

However sys_time also requires a memory address to be passed in ebx, where it writes the actual time.

A quick way would be to allocate some space on the stack (we can push anything on the stack, the sys_time value will overwrite it, why not stick the value of eax onto it).

push eax

Then feed the stack pointer into ebx

mov ebx, esp

Now make the system call

int 80h

Now we can pop the time off the stack (into e.g. eax)

pop eax

Now eax contains the current unix time (i.e. number of seconds since Jan 01 1970.)

To avoid the trickyness of printing numbers directly to the unix console I will cheat and provide a complete example that compiles in nasm and links with the c library via gcc and uses 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

Compile with

nasm -f elf sys_time.asm
gcc sys-time.o -o sys-time

Though if you are on 64-bit linux you might have to do (and have the relevant multilib gcc and glibc). You can't compile this program as a native 64-bit executable because it uses push and pop and you can't push a 32 bit register onto a 64 bit stack.

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

Then you should get

$ ./systime
1310190574

I've tested this on 32 bit and 64 bit linux and managed to get the above code compiled. Let me know if you have any problems.

To answer your question regarded nasm tutorials, I have been learning recently from "Assembly Language Step By Step, Third Edition" by Jeff Duntemann. See http://www.duntemann.com/assembly.html for details and sample chapters.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top