实现永远等待的汇编代码

Implement assembly code that waits forever

我想在 Arm 中编写简单而简短的汇编代码 Linux 永远等待。

label:
b label

可行,但需要很多 CPU 时间。

我考虑过使用 nanosleep 并每隔 X 秒跳转到标签,但如何在汇编中使用它?

pause 系统调用(在评论中建议)不好,因为进程有信号处理程序。

有简单的方法吗?

是的,你需要一个系统调用,是的,你的两个想法都是可行的。 (尽管 nanosleep 被限制为 time_t 可以表示的最大秒数。这可能“仅”在 ARM Linux 上是 2^31-1,这是著名的大约 68 年,从 1970 年开始的间隔 until 32-bit time overflows in 2038)

不过,Linux有一个专门针对这个的系统调用,pause(2):

pause() causes the calling process (or thread) to sleep until a signal is delivered that either terminates the process or causes the invocation of a signal-catching function

如果你没有安装信号处理程序,暂停不能 return,你只能退出(仍然通过点击 control-C,这会提供 SIGINT),或者通过杀死它(SIGTERM)或其他正常方式。

如果您确实安装了信号处理程序并希望保持暂停状态,那么显然您可以在循环中调用它。 (最好这样做,而不是在信号处理程序中调用 pause 而不是从中调用 returning )。在此短暂唤醒期间,您将仅使用 CPU 时间 运行 信号处理程序并重新启动主线程的执行,这将立即调用内核进行另一次暂停。

sleep 和 nanosleep 也在处理的信号上 return,根据手册页 returning -EINTR。 (libc 包装函数可能会为您重试/重新启动系统调用,但如果您想使用原始内核调用,您必须自己做。)


至于如何调用系统调用,搜索堆栈溢出(例如google与site:whosebug.com)ARM系统调用,或者只是google。鉴于手册页和将 C args 映射到寄存器的一般方法(调用约定),您可以调用任何东西。 What is the interface for ARM system calls and where is it defined in the Linux kernel?

暂停不需要任何参数,因此您只需要在正确的寄存器中输入电话号码 (__NR_pause):

@ arm_pause.S   - build with gcc -nostdlib arm_pause.S
#include <asm/unistd.h>   // contains only C preprocessor macros,  no C stuff.

.globl _start
_start:
  mov  r7, #__NR_pause
  swi  0x0

(未经测试;我只安装了 arm-none-eabi-gcc,没有安装 arm-linux-eabi-gcc。但确认 ARM Linux headers 确实有 __NR_pause,并使用内联asm 检查语法是否汇编:https://godbolt.org/z/PerGTx).