c++ - 有没有办法在 GCC 中禁用内联汇编程序?
问题描述
我正在为 LeetCode、Codeforces 等编程竞赛开发在线评委系统。对于大多数编程竞赛,C/C++ 中不允许使用内联汇编,所以我想在我的系统中添加相同的限制。
我想让GCC和G++在编译包含内联汇编的C/C++程序时产生错误,这样任何包含内联汇编的代码都会导致编译错误。
有没有办法做到这一点?我应该将一些命令行参数传递给 GCC/G++ 吗?
注意:禁用内联汇编只是为了遵守规则,而不是出于安全考虑。
解决方案
有没有办法在 GCC 中禁用内联汇编程序?
是的,有几种方法。
在编译器中关闭汇编
要在编译阶段执行此操作,请使用参数-fno-asm
。但是,请记住,这只会影响asm
而不是__asm__
。
文档:
-fno-asm
不要将“
asm
”、“inline
”或“typeof
”识别为关键字,以便代码可以使用这些词作为标识符。您可以改用关键字“__asm__
”、“__inline__
”和“__typeof__
”。-ansi
暗示-fno-asm
。在 C++ 中,此开关仅影响 "
typeof
" 关键字,因为 "asm
" 和 "inline
" 是标准关键字。您可能想改用-fno-gnu-keywords
标志,它具有相同的效果。在 C99 模式(-std=c99
或-std=gnu99
)下,此开关仅影响“asm
”和“typeof
”关键字,因为“inline
”是 ISO C99 中的标准关键字。
定义一个宏
您可以使用参数-Dasm=error -D__asm__=error
请注意,此构造是通用的。它的作用是创建宏。它的工作原理非常类似于#define
. 文档说:
-D name=definition
定义的内容被标记和处理,就好像它们出现在#define 指令中的第三阶段一样。特别是,定义将被嵌入的换行符截断。
...
因此,它所做的只是将asm
或的出现更改__asm__
为error
。这是在预处理器阶段完成的。您不必使用error
. 只需选择不会编译的任何内容。
使用在编译期间触发的宏
正如zwol评论中所建议的那样,一种在编译阶段使用宏来解决它的方法,您可以使用-D'asm(...)=_Static_assert(0,"inline assembly not allowed")'
. 如果存在名为 的标识符,这也将解决问题error
。
注意:此方法要求-std=c11
或更高。
在使用 gcc 之前使用 grep
另一种可能是解决您的问题的方法是grep
在编译之前在源代码树的根目录中执行以下操作:
grep -nr "asm"
这也会捕获__asm__
,但它可能会给出误报,例如,您有一个包含 substring 的字符串文字、标识符或注释"asm"
。但是在您的情况下,您可以通过禁止在源代码中的任何位置出现该字符串来解决此问题。只是改变规则。
可能出现的意外问题
请注意,禁用程序集可能会导致其他问题。例如,我无法使用stdio.h
此选项。系统头文件通常包含内联汇编代码。
一种欺骗上述方法的方法
可以将字符串作为机器代码执行。有关示例,请参见此答案:https ://stackoverflow.com/a/18477070/6699433
上面链接中的一段代码:
/* our machine code */
char code[] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x48,
0x89,0x75,0xf0,0xb8,0x2a,0x00,0x00,0x00,0xc9,0xc3,0x00};
/* copy code to executable buffer */
void *buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));
/* run code */
int i = ((int (*) (void))buf)();
上面的代码只是为了快速了解如何欺骗 OP 规定的规则。它并不是一个很好的例子来说明如何在现实中实际执行它。此外,代码不是我的。这只是我提供的链接中的简短代码引用。如果您对如何改进它有任何想法,请改为评论 4pie0:s 原帖。
推荐阅读
- javascript - 将一个js文件的重载函数导出并复用到另一个js文件中
- windows - cmd中的换行符“for in () do ()”
- ios - 如何更改 Firebase 实时数据库中子值的顺序
- sql - DB2 函数 动态行作为输入
- c - Linux 虚拟内存限制
- postgresql - psql 和触发器行为
- python-3.x - TensorFlow 2.0“构建”功能
- java - JavaFX 使用 SwingNode 嵌入 JFileChooser 并获取所选文件
- powerbi - 如何通过在 PowerBI 上从昨天相同的表值中减去今天的表值来创建新表并为差异值提供颜色编码?
- c++ - 使用三数比较器进行排序