- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
如果您正在编写一个对延迟非常敏感的应用程序,那么在 C++ 函数中嵌入汇编程序(并正常使用 C++ 函数调用)的限制是什么,如下所示:
inline __int64 GetCpuClocks()
{
// Counter
struct { int32 low, high; } counter;
// Use RDTSC instruction to get clocks count
__asm push EAX
__asm push EDX
__asm __emit 0fh __asm __emit 031h // RDTSC
__asm mov counter.low, EAX
__asm mov counter.high, EDX
__asm pop EDX
__asm pop EAX
// Return result
return *(__int64 *)(&counter);
}
(以上功能来 self 看到的另一个SO帖子)
您能否将汇编程序内联函数视为黑匣子?您能否轻松地从汇编程序中执行的计算中检索结果?是否存在您不知道寄存器等中当前有哪些变量的危险?它导致的问题多于解决的问题,还是对于特定的小任务来说是可以接受的?
(假设您的架构将被修复并为人所知)
编辑我刚发现这个,这就是我要暗示的:
http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C
EDIT2 这更针对 Linux 和 x86——它只是一个一般的 C++/汇编程序问题(或者我认为如此)。
最佳答案
我想回答子问题:
Does it cause more problems than solve, or is it acceptable for specific small tasks?
确实如此!使用内联汇编器,您可以利用编译器优化代码的能力。它不能进行部分表达式替换或任何其他奇特的优化。生成比编译器使用 -O3 发出的代码更好的代码真的非常困难。作为奖励,代码在下一个编译器版本中变得更好(假设下一个编译器版本不会破坏它;))。
编译器通常比人类大脑能够(或应该,以确保理智)掌握更广泛的范围,能够在正确的位置内联正确的函数,进行部分表达式替换,从而使代码更高效。您在 ASM 中永远不会做的事情,因为您的代码变得难以阅读。
作为轶事引用,我想 this post由 Linus Torvalds 撰写,与 SHA1 的 git 实现有关,它优于 libcrypt 中手动优化的 SHA1。
事实上,我认为现在唯一合理使用内联汇编程序的是调用处理器指令,否则这些指令是不可用的(你引用的那个是可用的,例如在 linux 上作为 clock_gettime
,至少如果你只是在一个高分辨率的时间计数器之后)或者如果你必须在需要欺骗编译器的地方做一些事情(例如在外部函数接口(interface)的实现过程中)。
关于片段和其他人所说的。特别是对于这样的功能,您会受到性能损失。在内联 asm 中,您必须格外小心,确保寄存器保持编译器假定的状态(push/pop,如上所述)。而如果您正常编写代码,编译器会注意并准确地保留那些在寄存器中有意义的变量和那些不适合堆栈的变量。
相信你的编译器。这很聪明。大多数时候。将通过不使用内联汇编器节省的时间用于思考智能、快速的算法和学习相关的编译器开关(例如启用 SSE 优化等)。
关于c++ - 在 C++ 中嵌入汇编器可以接受吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13827850/
某些 AMD64/x86 命令需要立即值作为操作数(例如 imm8)。是否可以使用存储在某个寄存器中的值(例如 ah)来代替这个硬编码值? 例如: 如果我想移动 xmm 寄存器,可以使用 pslldq
您好,我正在修改汇编级编程。我有以下代码 mov al, 'H' call my_function my_function: mov ah,0x0e ;
x86 汇编程序例程通常以以下序言开始: push ebp ; Save ebp mov ebp, esp ; Set
这个问题已经有答案了: What is the purpose of XORing a register with itself? [duplicate] (7 个回答) 已关闭 2 年前。 我们有时
如果您不了解二进制,我知道 BCD 是更直观的数据类型。但我不知道为什么要使用这种编码,它好像没有多大意义,因为它浪费以 4 位表示(当表示大于 9 时)。 另外,我认为 x86 仅支持直接添加和替换
x86 汇编程序例程通常以以下序言开始: push ebp ; Save ebp mov ebp, esp ; Set
var a int[1]; var aa int[1]; aa = a; 假设我们想在 java jvm 中编译这样的东西。看起来人们只会做一个 ldc 1 newarray int astor
是否有任何编写 MIPS 汇编器的引用指南或教程? 最佳答案 如果您希望实际编写汇编程序,您需要知道您正在编写的平台的可执行文件的格式(例如 ELF ),那么您需要使用 MIPS instructio
我想写一个简单的 M.A.R.I.E.计算表达式 A x B + C x D 的程序. 现在,关于 Marie 汇编语言的信息并不多。我不确定是否有乘法?如果没有,我是否必须循环或其他东西才能使其成倍
我想知道为 NASM 编写汇编代码的格式是什么。有什么地方教的吗?我尝试在 NASM 上运行 MASM32 文件,但我认为它无法识别指令。 最佳答案 总是有 the manual . 关于linux
我想要的是类似 g++ 的东西,我可以在其中输入: compiler_name my_assembly_code.extention ...并让它编译我的汇编代码。它是 32 位还是 64 位并不重要
我正在为 8086 开发一个汇编程序。我的问题是如何将十六进制操作码转换为可执行文件,如 .EXE、.ELF、.COM、a.out 等。为此寻找链接/资源,汇编程序应该执行链接过程还是由操作系统自动?
我想编写 64 位 Windows 程序集(最好使用 NASM)。我在谷歌上看起来很不错,但似乎找不到 64 位 Windows 编译器。一些站点提到了 ml64,但它似乎不再包含在 VC++ 中。我
使用 GNU Binutils 声明汇编代码时,例如: .long MY_Label .long MY_Second_label 即使操作码和其他信息在地址空间中将它们分开,也可以在进行十六进制转储时
似乎单元测试这些天变得风靡一时,我知道你们中的许多人会想:“那么为什么不直接使用语言 X 和框架 Y 呢?”但我提出这个想法更多是为了证明概念,或者是出于对我早年计算机编程的怀念。 我正在研究使用 N
作为编译器项目的一部分,我必须为 x86 编写 GNU 汇编器代码来比较浮点值。我试图找到有关如何在线执行此操作的资源,据我了解,它的工作原理如下: 假设我要比较的两个值是浮点堆栈上的唯一值,则 fc
操作系统:Windows 10 CPU:英特尔酷睿 i5-5300U 架构:x64 我刚刚开始学习汇编语言。我使用了在线编译器,但今天我下载了NASM。我尝试编写这个将 10 乘以 15 的简单代码:
查看以下代码: (ebp-0x8 -> int) (ebp-0x4 -> int*) => 0x80483f3 : mov DWORD PTR [ebp-0x8],0x0 0x80483
我需要编写一个类似 CorFlags 的应用程序。如果我有程序集文件的路径,我该如何读取它的 CorFlags? 我特别需要知道程序集是 Any-CPU 还是仅 x86 我想避免使用反射加载程序集,因
查看以下代码: (ebp-0x8 -> int) (ebp-0x4 -> int*) => 0x80483f3 : mov DWORD PTR [ebp-0x8],0x0 0x80483
我是一名优秀的程序员,十分优秀!