简体   繁体   中英

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

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:

 ;; This is for 32-bit.  Note that x86-64 uses 2x 64-bit 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_usec dd 0

and then you sets the values and call it as:

mov dword [tv_sec], 5
mov dword [tv_usec], 0
mov eax, 162
mov ebx, timeval
mov ecx, 0
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_usec], 0
  mov eax, 162
  mov ebx, timeval
  mov ecx, 0
  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_usec dd 0

  bmessage  db "Sleep", 10, 0
  bmessagel equ $ - bmessage

  emessage  db "Continue", 10, 0
  emessagel equ $ - emessage

With NASM, if you are targeting Linux x86-64, you can simply do something similar to the following:

global _start

section .data

    timespec:
        tv_sec  dq 1
        tv_nsec dq 200000000

section .text

    _start:
        mov rax, 35
        mov rdi, timespec
        xor rsi, rsi        
        syscall
        ...

35 corresponds to the 64-bit system call number for sys_nanosleep (as listed here ). If the call is interrupted, the remaining sleep time is written to the memory location pointed by register rsi ; in this example rsi is set to 0 to ignore the value if it happens. This call will sleep for tv_sec seconds + tv_nsec nanoseconds , 1.2 seconds in the above code snippet.

More information about this system call can be found in the nanosleep man page .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM