我试图找到一种方法让我的代码在继续之前等待两秒钟。我在保护模式下使用 nasm for Linux,所以我只能使用 int 80h。我找到了一个syscall
叫“ alarm
”(27)和另一个叫“ 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
问问题
5967 次
2 回答
9
有一个睡眠程序的系统调用,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
于 2013-10-25T03:29:04.870 回答
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
对应于 64 位系统调用号(如此处sys_nanosleep
所列)。如果调用被中断,剩余的睡眠时间被写入寄存器指向的内存位置;在此示例中设置为 0 以忽略该值(如果发生)。此调用将休眠tv_sec 秒 + tv_nsec 纳秒,在上面的代码片段中为 1.2 秒。rsi
rsi
关于这个系统调用的更多信息可以在nanosleep 手册页中找到。
于 2017-04-15T10:47:10.957 回答