Search code examples
linuxassemblytimersleepnasm

nasm assembly linux timer or sleep


I'm trying to find a way to make my code wait for two seconds before proceeding. I'm using nasm for Linux in protected mode, so I can only use int 80h. I found a syscall called "alarm" (27) and another called "pause" (29). However, when I try to use those, the program waits and finishes instead of continuing execution. I've also found another syscall, sigaction, which changes the behavior of a signal (so I think it can be used to make the program ignore the signal generated by alarm instead of exiting) but I didn't quite understand how sigaction works. Thanks for any help. Useful links:http://man7.org/linux/man-pages/man2/alarm.2.html http://man7.org/linux/man-pages/man2/sigaction.2.html


Solution

  • There is a system call for sleeping the program, sys_nanosleep:

     sys_nanosleep : eax = 162, ebx = struct timespec *, ecx = struct timespec *
    

    this struct timespec structure has two members:

    tv_sec   ; 32 bit seconds
    tv_nsec  ; 32 bit nanoseconds
    

    this structure can be declared in nasm as:

    section .data
    
      timeval:
        tv_sec  dd 0
        tv_nsec dd 0
    

    and then you sets the values and call it as:

    mov dword [tv_sec], 5
    mov dword [tv_nsec], 0
    mov eax, 162
    mov ebx, timeval
    mov ecx, timeval
    int 0x80
    

    the program then will sleep for 5 seconds. A complete example:

    global  _start
    
    section .text
    _start:
    
      ; print "Sleep"
      mov eax, 4
      mov ebx, 1
      mov ecx, bmessage
      mov edx, bmessagel
      int 0x80
    
      ; Sleep for 5 seconds and 0 nanoseconds
      mov dword [tv_sec], 5
      mov dword [tv_nsec], 0
      mov eax, 162
      mov ebx, timeval
      mov ecx, timeval
      int 0x80
    
      ; print "Continue"
      mov eax, 4
      mov ebx, 1
      mov ecx, emessage
      mov edx, emessagel
      int 0x80
    
      ; exit
      mov eax, 1
      mov ebx, 0
      int 0x80
    
    section .data
    
      timeval:
        tv_sec  dd 0
        tv_nsec dd 0
    
      bmessage  db "Sleep", 10, 0
      bmessagel equ $ - bmessage
    
      emessage  db "Continue", 10, 0
      emessagel equ $ - emessage