nasm 程序集 linux 计时器或睡眠

Posted

技术标签:

【中文标题】nasm 程序集 linux 计时器或睡眠【英文标题】:nasm assembly linux timer or sleep 【发布时间】:2013-11-04 00:10:46 【问题描述】:

我正在尝试找到一种方法让我的代码在继续之前等待两秒钟。我在保护模式下使用 nasm for Linux,所以我只能使用 int 80h。我找到了一个名为“alarm”(27)的syscall,另一个名为“pause”(29)。但是,当我尝试使用它们时,程序会等待并完成而不是继续执行。我还发现了另一个syscall,sigaction,它改变了信号的行为(所以我认为它可以用来让程序忽略警报生成的信号而不是退出)但我不太明白 sigaction 是如何作品。谢谢你的帮助。 有用链接:http://man7.org/linux/man-pages/man2/alarm.2.html http://man7.org/linux/man-pages/man2/sigaction.2.html

【问题讨论】:

阅读time(7) 并点击链接到那里的其他手册页。 更正一下,你是在 nasm 中进行用户空间编程,所以你没有处于保护模式。 【参考方案1】:

有一个系统调用让程序休眠,sys_nanosleep:

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

这个struct timespec 结构有两个成员:

 ;; This is for 32-bit.  Note that x86-64 uses 2x 64-bit members
tv_sec   ; 32 bit seconds
tv_nsec  ; 32 bit nanoseconds

这个结构可以在 nasm 中声明为:

section .data

  timeval:
    tv_sec  dd 0
    tv_usec dd 0

然后您设置值并将其称为:

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

然后程序将休眠 5 秒。一个完整的例子:

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

【讨论】:

【参考方案2】:

使用 NASM,如果您的目标是 Linux x86-64,您可以简单地执行类似以下的操作:

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 对应于 sys_nanosleep 的 64 位系统调用号(如列出的 here)。如果调用中断,则将剩余的休眠时间写入寄存器rsi指向的内存位置;在此示例中,rsi 设置为 0 以在发生该值时忽略该值。此调用将休眠 tv_sec 秒 + tv_nsec 纳秒,在上述代码 sn-p 中为 1.2 秒。

关于这个系统调用的更多信息可以在nanosleep man page找到。

【讨论】:

以上是关于nasm 程序集 linux 计时器或睡眠的主要内容,如果未能解决你的问题,请参考以下文章

NASM 程序集将输入转换为整数?

为啥 Xcode 命令行 nasm 程序集发出错误:unknown use of instruction mnemonic without a size suffix

将两个32位数相乘并将64位结果打印为十进制NASM程序集

为什么具有对_GLOBAL_OFFSET_TABLE_的非限定引用的nasm程序集显然可以组装并链接为PIC?

linux下定时器的使用--timer_create等函数集

x86 AT&T 语法程序集的注释语法