现代如何使用汇编(例如 C/C++)?

2024-03-04

我了解计算机如何按照基本原理工作,例如,可以用 C#、C 等“高级”语言编写程序,然后将其分解为目标代码,然后分解为二进制代码以供处理器理解。然而,我真的很想了解汇编,以及它如何在现代应用程序中使用。

我知道处理器在基本 x86 指令集之上有不同的指令集。所有汇编语言都支持所有指令集吗?

汇编语言有多少种?有多少可以与其他语言兼容?

有人会如何用汇编语言编写例程,然后将其编译为对象/二进制代码?

然后,人们如何从 C 或 C++ 等语言引用该汇编代码中的函数/例程?

我们如何知道用汇编语言编写的代码是最快的?

有没有关于汇编语言/在现代程序中使用它们的推荐书籍?

对于问题的数量感到抱歉,我确实希望它们足够普遍,对其他人有用,并且足够简单,便于其他人回答!


However, I really want to learn about assembly, and how it's used in modern day applications.

在“普通”PC 上,它仅用于时间关键的处理,我想说,实时多媒体处理仍然可以从手工锻造装配中受益匪浅。在嵌入式系统上,马力要少得多,它可能有更多的使用领域。

但是,请记住,这不仅仅是“嘿,这段代码很慢,我将用汇编重写它,它会神奇地变快”:它必须仔细编写汇编,编写knowing在您的特定架构上,什么是快的,什么是慢的,并牢记现代处理器的所有复杂性(分支错误预测、无序执行……)。通常,初级到中级汇编程序员编写的汇编程序将是slower比由优秀的现代优化编译器生成的最终机器代码更好。 x86 上的性能问题通常非常复杂,应该留给那些知道自己在做什么的人 => 他们中的大多数都是编译器编写者。 :) 看一下this http://web.archive.org/web/20160801143844/https://blogs.msdn.microsoft.com/oldnewthing/20041216-00/?p=36973/, 例如。用于测试 Collat​​z 猜想的 C++ 代码比手写汇编更快 - 为什么? https://stackoverflow.com/questions/40354978/c-code-for-testing-the-collatz-conjecture-faster-than-hand-written-assembly深入了解该情况下的一些特定 x86 细节,您必须了解这些细节才能在单个小循环中匹配或击败启用优化的编译器。

I know processors have different instruction sets above the basic x86 instruction set. Do all assembly languages support all instruction sets?

我认为你在这里混淆了一些事情。许多(=全部现代)x86处理器支持在原始指令和指令集之后引入的附加指令和指令集x86指令集被定义。实际上,现在几乎所有 x86 软件都是为了利用后 Pentium 功能而编译的,例如cmovcc https://www.felixcloutier.com/x86/cmovcc;您可以使用以下命令查询处理器以查看它是否支持某些功能CPUID http://en.wikipedia.org/wiki/CPUID操作说明。显然,如果您想对某些较新的指令集指令使用助记符,您的汇编器(即在实际机器代码中翻译助记符的软件)必须了解它们。

大多数 C 编译器都有内在函数 like _mm_popcnt_u32和/或命令行选项,例如-mpopcnt使它们能够让您利用新指令而无需手写汇编。 x86-mbmi / -mbmi2扩展有几个编译器知道如何在优化普通 C 时使用的指令,例如x << y (shlx https://www.felixcloutier.com/x86/sarx:shlx:shrx而不是更笨重的shl https://www.felixcloutier.com/x86/sal:sar:shl:shr) or x &= x-1; (blsr / _blsr_u32() https://www.felixcloutier.com/x86/blsr)。海湾合作委员会有一个-march=native选项启用您的 CPU 支持的所有指令集,并设置-mtune=根据循环展开量或哪些指令或序列在一个 CPU 上更快、在另一个 CPU 上更慢来优化 CPU 是一个好主意。

相反,如果您正在谈论其他系列处理器的其他(非 x86)指令集,那么每个汇编器都应该支持目标处理器可以运行的指令。并非汇编语言的所有指令都可以直接替换其他语言,并且通常将汇编代码从一种体系结构移植到另一种体系结构通常是一项艰巨的工作。


How many assembly languages are there?

理论上,每个处理器系列至少有一种方言。请记住,同一汇编语言也有不同的表示法;例如,以下两条指令是用 AT&T 和 Intel 表示法编写的相同 x86 内容:

mov $4, %eax          // AT&T notation

mov eax, 4            // Intel notation
How would someone go about writing a routine in assembly, and then compiling it in to object/binary code?

如果您想将例程嵌入到用另一种语言编写的应用程序中,您应该使用该语言提供的工具,在 C/C++ 中您可以使用asm blocks.

您可以改为独立制作.s or .asm例如,使用与 C 编译器输出相同语法的文件gcc -O3 -S将编译为.s您可以使用它进行汇编的文件gcc -c。如果您想在 asm 中编写整个函数而不是包装一条或几条指令,那么单独的文件是一个好主意。 x264 和 x265(视频编码器)等一些开源项目拥有大量 NASM 源代码,适用于不同版本的 SSE 或 AVX 的不同版本的功能。

相反,如果您想用汇编语言编写整个应用程序,则必须遵循您要使用的汇编器的语法规则,仅在汇编语言中编写。

How do we know the code we've written in assembly is the fastest it possibly can be?

理论上,因为它最接近裸机,所以您可以让机器完全按照您的意愿行事,而无需让编译器考虑在某些特定情况下无关紧要的语言功能。在实践中,由于机器通常比汇编语言公开的要复杂得多,正如我所说,汇编语言通常会比编译器生成的机器代码慢,因此考虑到了普通程序员不知道的许多微妙之处。


Addendum

我忘记了:知道阅读汇编,至少一点点,可以very对于调试优化器损坏时可能出现的奇怪问题很有用/仅在发布版本中/您必须处理 heisenbugs/当源代码级调试不可用或其他类似的东西时;看看评论here http://web.archive.org/web/20190118214328/https://blogs.msdn.microsoft.com/oldnewthing/20041111-00/?p=37333.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

现代如何使用汇编(例如 C/C++)? 的相关文章

  • 从 SQL 数据库获取日期时间

    我的数据库表中有一个 DateTime 记录 我编写一个查询从数据库中获取它 string command2 select Last Modified from Company Data where Company Name Descrip
  • 如何自定义 DataTable 列的排序

    我需要对数据表列的值进行排序 该列包含字符串 整数或混合文本 例如 数据表列包含如下值 23 18 12 store 23 store a1 1283 25 如果我使用对值进行排序Dataview sort 方法会按此顺序产生 12 128
  • LINQ to XML - 如何正确使用 XDocument

    现在我首先要说的是 这确实是一项任务 然而 在我遇到 Linq to XML 语法之前 我几乎已经完成了它 我有 2 个课程 曲目和 CD 现在作为作业的一部分 我创建了一张 CD 然后向其中添加了一些曲目 在搜索了大量完美解释了如何从 x
  • .NET 可移植类库中的 .ToShortDateString 发生了什么

    我想知道为什么没有 ToShortDateString在 NET 可移植类库中 我有 2 个项目 Silverlight 和常规 NET 类库 使用相同的代码 并且代码涉及调用 ToShortDateString on a DateTime
  • __FUNCTION__ 宏的 C# 版本

    有人对 C FUNCTION 宏的 C 版本有好的解决方案吗 编译器似乎不喜欢它 尝试使用这个代替 System Reflection MethodBase GetCurrentMethod Name C 没有 LINE or FUNCTI
  • 阅读 Stack Overflow RSS 源

    我正在尝试获取未回答问题的列表the feed https stackoverflow com feeds 但我在阅读时遇到困难 const string RECENT QUESTIONS https stackoverflow com f
  • 组合 Datepicker 和 Timepicker 值 Win 8.1

    我试图同时使用 Datepicker Timepicker 来返回可以存储在数据库中的 DateTime 例如 我想要安排会议的开始日期和结束日期 如果适用 我将如何将这些值组合成 SQL 数据库可以处理的正确格式 任何反馈都会很棒 我让这
  • 控制台应用程序 .net Core 2.0 的配置

    在 net Core 1 中我们可以这样做 IConfiguration config new ConfigurationBuilder AddJsonFile appsettings json true true Build 这样就可以使
  • 成员初始值设定项列表中的求值顺序是什么?

    我有一个带有一些参数的构造函数 我假设它们是按照列出的顺序初始化的 但在一种情况下 它们似乎是按相反的顺序初始化的 导致中止 当我反转参数时 程序停止中止 下面是我正在使用的语法的示例 a 之前需要初始化b 在这种情况下 你能保证这个初始化
  • CMake - 将预构建库链接到 C# 项目

    我正在使用 CMake 构建 C 库 该库依赖于已构建的库 dll 我似乎无法让图书馆链接到我的图书馆 我尝试过使用target link libraries mylib external lib 我也尝试过暴力破解 reference e
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • for 循环 - 没有效果的语句

    由于某种原因 我收到错误 statement with no effect关于这个声明 for j idx j lt iter j increment printf from loop idx i int idx punc ctxt j 你
  • _mm_max_ss 在 clang 和 gcc 之间有不同的行为

    我正在尝试使用 clang 和 gcc 交叉编译一个项目 但在使用时发现一些奇怪的差异 mm max ss e g m128 a mm set ss std numeric limits
  • 在生产者-消费者情况下使用条件变量

    我正在尝试了解条件变量以及如何在生产者 消费者情况下使用它 我有一个队列 其中一个线程将数字推入队列 而另一个线程从队列中弹出数字 当生产线程放置一些数据时 我想使用条件变量向消费线程发出信号 问题是有时 或大多数时候 它只将最多两个项目推
  • 如何使用 Clang 查找内存泄漏

    我在我的机器 ubuntu 中安装了 Clang 以便发现我的 C 代码中的内存泄漏 我编写了一个示例代码来检查它的工作情况 如下所示 File hello c for leak detection include
  • 如何从枚举中选择随机值?

    给定 C 中的任意枚举 如何选择随机值 我没有找到这个非常基本的问题 我会在一分钟内发布我的答案作为任何人的参考 但请随意发布你自己的答案 Array values Enum GetValues typeof Bar Random rand
  • 用 C# 编写的带有点击移动的 WPF 游戏

    我试图将标签网格移动到鼠标的位置 就像冒险游戏中的移动一样 理想情况下 我会在途中删除并重新绘制它们 但是 现在我只想弄清楚如何将 int 转换为厚度或 pointtoscreen 到目前为止我有 player XMove int Mous
  • 为什么我不能在扩展 List 的类中调用 OrderBy?

    我有一堂课 Deck 其中包含一个名为的方法Shuffle 我正在致力于重构Deck延长List
  • 在 C# 中读取/写入命令行程序

    我正在尝试与 C 的命令行程序进行对话 它是一个情绪分析器 它的工作原理如下 CMD gt java jar analyser jar gt Starting analyser 这是我想从我的 C 程序插入内容的地方 例如 I love y
  • 最后从同一类中的其他构造函数调用构造函数

    我在这里读到可以调用另一个构造函数从同一类中的另一个构造函数调用构造函数 https stackoverflow com questions 829870 calling constructor from other constructor

随机推荐