博文以以下关机代码来讲解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include </usr/include/linux/reboot.h>
...
int Shutdown(int argc,char* argv[]){
int result_code = -1;
int shutdown_code = 88;
int magic_1 = LINUX_REBOOT_MAGIC1;
int magic_2 = LINUX_REBOOT_MAGIC2;
int shutdown_command = LINUX_REBOOT_CMD_POWER_OFF;
asm volatile(
"movl %1,%%eax \n\t"
"int $0x80 \n\t"
"movl %%ebx,%0 \n\t"
: "=m"(result_code)
: "r"(shutdown_code),"ebx"(magic_1),"ecx"(magic_2),"edx"(shutdown_command)
);
printf("the result code is %d",&result_code);
}
...
其中关机需要两个幻数为的是防止误操作,防止系统出现错误导致误调用关机。
- 两个幻数和关机指令是在
/usr/include/linux/reboot.h
中定义
在Linux
内核中,我们可以使用0x80
系统中断调用号来实现系统调用。
中断调用汇总见博文:https://blog.csdn.net/xiaominthere/article/details/17287965
在C/C++中,我们使用asm volatile来内嵌汇编代码,注意:要分清楚32位和64位汇编
汇编结构:
1
2
3
4
5
6
__asm__(
汇编语句模板:
输出部分:
输入部分:
破坏描述部分;
)
我们拿出关机代码中的汇编代码
1
2
3
4
5
6
7
8
asm volatile(
"movl %1,%%eax \n\t"
"int $0x80 \n\t"
"movl %%ebx,%0 \n\t"
: "=m"(result_code)
: "r"(shutdown_code),"ebx"(magic_1),"ecx"(magic_2),"edx"(shutdown_command)
: "eax"
);
其中:
- 表示寄存器的
%
需要双写转义。 %n
表示后面传的第n
个参数,比如上述的shutdown_code
为第1个参数,result_code
为第0个参数,等等。"r"
表示该变量放到某一个寄存器中,由编译器决定;ebx(variable)
表示在执行这些汇编代码前,将相关C++变量值复制到ebx
寄存器中- 最后的
eax
表示这段代码会破坏eax
的原有内容
执行效果如下: