- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在使用 Linux 的 nanosleep 系统调用时遇到了一些问题。这段代码应该在退出前等待 2 秒,但它并没有:
.text
.globl _start
_start:
pushq %rbp
movq %rsp,%rbp
pushq $0 #0 nanoseconds
pushq $2 #2 seconds
leaq (%rbp),%rdi #the time structure on the stack
movq $35,%rax #nanosleep syscall
movq $0,%rsi #disable useless parameter
syscall
leave
最佳答案
在 push
之后把东西放在堆栈上,使用 mov %rsp, %rdi
. RSP(当前堆栈指针)指向您新推送的结构,而不是 RBP(帧指针)。 lea (%rsp), %rdi
是一种效率较低的写法,但也可以。
您正在通过 RBP
作为指针,但它仍然指向制作“堆栈框架”时保存的 RBP 值。注意是_start
,不是一个函数,所以你实际上只是终止了保存的 RBP 值的链表。 System V ABI 建议通过将 RBP 显式设置为零来执行此操作,但 Linux 会在进程启动时将寄存器(RSP 除外)置零,因此这是有效的。
无论如何,在 _start
, (rsp)
是argc
, 然后你推 0
(保存的 RBP)并将 RBP 设置为指向那里。所以你传递给 sys_nanosleep
的结构是{0, argc}
.或者 argc
纳秒。 (使用 strace
进行测试,看看我是否做对了;我没有尝试。)
这是你应该做的:
pushq $0 #0 nanoseconds
pushq $2 #2 seconds
### RSP instead of RBP in the next instruction:
mov %rsp, %rdi #the time structure we just pushed
mov $35, %eax #SYS_nanosleep
xor %esi, %esi #rem=NULL, we don't care if we wake early
syscall
# RSP is 16 bytes lower than it was before this fragment, in case that matters for later code.
我还通过在不需要时不使用 64 位操作数大小进行了优化(因为写入 32 位寄存器会将高 32 位归零)。我喜欢让寄存器大小暗示操作数大小而不是使用 movq
,就像在 Intel 语法中一样。我还使用惯用的方式将寄存器归零,并改进了评论。
您建议的答案已损坏:subq $16, %rbp
之前leave
这是坏的主意。
如果您想相对于 RBP 栈帧寻址新插入的结构,您可以 lea -16(%rbp), %rdi
.
但修改%rbp
将使 leave
设置 RSP
到更新的RBP
然后将结构的低 qword 弹出到 RBP
,而不是调用者保存的 RBP
. RSP 将指向结构的高位 qword,而不是函数返回地址。
这可能只有效,因为你只使用 sys_exit
在 leave
之后,因为你不在一个函数中,所以你不能 ret
反正。使用 leave
没有意义在 _start
,因为它不是函数。你只需要 sys_exit
或 sys_exit_group
.
但是如果您在实际函数中使用此片段,它会破坏堆栈。
关于linux - 如何在 x86 程序集中使用 "nanosleep"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48489860/
我正在尝试在 Linux 中使用库插入来 Hook 函数调用。我捕捉得很好,但有些情况我遗漏了……其中一个是 nanosleep()。我正在挂接的二进制文件每隔一秒就会使用此函数使线程休眠...如果我
我正在查看来自嵌入式 MIPS Linux 应用程序的核心转储。 GDB 正在报告 SIGBUS,并且处理信号的线程似乎位于 nanosleep 的系统调用中 - 更高级别的代码基本上称为 sleep
我有一个使用 nanosleep 的程序(混合了 C 和 Fortran,虽然这似乎不相关)。但是,如果我的 timespec 的 tv_sec 值为 0,它就不会休眠。 tv_nsec 值可能比整秒
在我的工作场所中的并发代码中,多次发生具有非零常量的nanosleep()或usleep(),以释放CPU而不依赖于futex(),或者使用 sleep 同步原语使线程进入休眠状态(例如例如,等待并发
我需要使用 nanosleep我的用户空间线程库中的函数来实现大约所需数量的等待,因为它可以在异步信号中断的情况下节省剩余时间。我使用 SIGALRM 抢先切换线程;因此,重要的是要考虑使用不可重入函
我编写了以下代码,以 0.3 秒的间隔逐个字符地打印段落。但是当我编译并运行它时,它会在句子中打印所有内容。为什么纳秒函数不起作用? #include #include #include #in
我在 while 循环中有一个 nanosleep 函数。这是我在《Linux系统编程:直接与内核和C库对话》一书中找到的一个例子 while(nanosleep(a, b) && errno
这段代码会做什么? struct timespec wait; wait.tv_sec = 0; wait.tv_nsec = 0; nanosleep(&wait, NULL); 或 ... c
我想知道 sleep/nanosleep 内部是如何实现的?考虑这段代码: { // on a thread other than main() thread while(1) { /
我正在使用 nanosleep 将进程停止一段时间。如何在要求的时间之前中断 nanosleep?谢谢! 最佳答案 如@Kerrek SB 所述,设置一个信号处理程序来处理 SIGUSR1,使用 ki
我注意到一个调用 nanosleep 的小测试程序在内核高于 2.6.22 的 Linux 机器上运行时显示 CPU 使用率的巨大差异。 #include int main (void) {
Unix 有多种 sleep API(sleep、usleep、nanosleep)。我所知道的唯一用于 sleep 的 Win32 函数是 Sleep(),它以毫秒为单位。 我看到大多数 sleep
我正在尝试在我的代码中测试 nanosleep 的性能。当我调用 nanosleep 并在 0 秒和 0 纳秒内传递时,与甚至不调用 nanosleep 相比,我得到了不同的值。如果我用 0 作为参数
我想在我的代码中用 nanosleep 替换过时的 usleep 函数: static int timediff( struct timeval *large, struct timeval *sma
我在使用 Linux 的 nanosleep 系统调用时遇到了一些问题。这段代码应该在退出前等待 2 秒,但它并没有: .text .globl _start _start: pushq %rbp m
我在 g++ 中编译了以下测试,nanosleep 太长了,它需要 60 微秒完成,我预计它只花费不到 1 微秒: int main() { gettimeofday(&startx, NUL
我想用我的 RaspberryPi 3 驱动步进电机。我需要每秒生成大约 10000 个脉冲,这意味着我需要以大约 100us 的间隔生成脉冲。我知道 Raspberry 可以生成 PWM,但事实并非
我有一个 C 程序,它使用 for(;;) 从/向套接字执行接收/发送操作。循环和一个 select()监视文件描述符。我还需要这个程序每 80 毫秒向一个数据包发送一个数据包,我该如何实现呢?也许我
我有 2 个与 C 语言 Linux 系统编程相关的理论问题,关于 nanosleep 和进程破坏。 所以,第一个: 仅使用nanosleep就可以使CPU负载达到97%。例如,让我们考虑一个在子进程
这个问题在这里已经有了答案: How to use nanosleep for sleeping random amounts of time? (2 个答案) 关闭 8 年前。 我知道这是一个新手
我是一名优秀的程序员,十分优秀!