c - Windows 中 asm("nop") 的实现
问题描述
以分号结尾的空代码行是否等同于 asm("nop") 指令?
volatile int x = 5;
if(x == 5){
printf("x has not been changed yet\n");
}
else{
;//Is this the same as asm("nop") or __asm nop in windows?
//alternatively could use __asm nop or __nop();
}
我查看了这个答案,这让我不想使用 x86 特定的使用内联汇编的实现。 `__asm nop` 是 GCC 编译器的 `asm volatile("nop");` 的 Windows 等价物吗
我可以使用这个 void __nop(); msdn似乎推荐的功能,但如果我不需要,我不想在库中拖动。 https://docs.microsoft.com/en-us/cpp/intrinsics/nop?view=vs-2017
有没有一种便宜的、可移植的方法来添加一个不会被编译出来的 nop 指令?我认为一个空分号要么是 nop 要么是编译出来的,但由于某种原因我今晚找不到任何关于它的信息。
澄清编辑 我可以使用内联 asm 为 x86 执行此操作,但我希望它是可移植的。我可以使用 Windows 库 __nop() 但我不想将该库导入到我的项目中,这是不受欢迎的开销。
我正在寻找一种更简洁的方法来生成不会被优化的 NOP 指令(最好使用标准 C 语法),可以将其制成 MACRO 并在整个项目中使用,具有最小的开销和工作(或者可以很容易地改进为工作)在 windows/linux/x86/x64 上。
谢谢。
解决方案
我的意思是我不想添加一个库只是为了强制编译器添加一个 NOP。
...以一种独立于编译器设置(例如优化设置)的方式,并且以一种适用于所有 Visual C++ 版本(甚至可能是其他编译器)的方式:
没有机会:只要汇编代码具有 C 代码所描述的行为,编译器就可以自由地生成代码。
而且因为NOP
指令不会改变程序的行为,编译器可以自由地添加或忽略它。
即使您找到了一种强制编译器生成的方法NOP
:编译器的一个更新或修改某些文件的 Windows 更新,编译器也可能不再生成NOP
指令。
我可以使用内联汇编来为 x86 执行此操作,但我希望它是可移植的。
正如我在上面所写的,任何强制编译器编写 a 的NOP
方法都只能在特定 CPU 的特定编译器版本上工作。
使用内联汇编,或者__nop()
您可能涵盖某个制造商的所有编译器(例如:所有 GNU C 编译器或 Visual C++ 的所有变体等......)。
另一个问题是:您是否明确需要“官方”NOP
指令,或者您是否可以接受任何什么都不做的指令?
如果您可以忍受任何(几乎)什么都不做的指令,那么读取全局或静态volatile
变量可以替代NOP
:
static volatile char dummy;
...
else
{
(void)dummy;
}
这应该强制编译器添加一条MOV
读取变量的指令dummy
。
背景:
如果您编写了设备驱动程序,则可以将变量链接dummy
到读取变量具有“副作用”的某个位置。示例:读取位于 VGA 显存中的变量会影响屏幕内容!
使用volatile
关键字你不仅告诉编译器变量的值可能随时改变,而且读取变量可能会产生这样的效果。
这意味着编译器必须假设不读取变量会导致程序无法正常工作。它无法优化MOV
读取变量的(实际上是不必要的)指令。
推荐阅读
- objective-c - swift中的动态子类实例化
- php - Model QueryException Array 中的数据库连接 Laravel 到字符串的转换“(SQL: CALL to prc_users_insert(12,,1,,,akhtar,munir,,,))”
- typescript - 如何在 Type Script 中导入 CSV 文件和文本文件
- python - ModuleNotFoundError:没有名为 msg1 的模块(在带有 python 2.7.6 的 ubuntu 中没有显示任何错误)
- c# - .netcore EF linq - 这是一个错误吗?非常奇怪的行为
- ibm-cloud - Node-Red 应用程序再次询问“欢迎使用您的新 Node-RED 实例”
- javascript - TYPO3 前端:未找到表单操作结果页面
- java - 如何参考 TestNG 从 POM.XML 运行特定的 Java 类
- debugging - NuGet/MyGet 调试抛出未找到源代码错误
- sql - 每组记录只显示一次值