为什么在有了编译器时甚至还需要汇编器? [英] Why do we even need assembler when we have compiler?

查看:223
本文介绍了为什么在有了编译器时甚至还需要汇编器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果编译器将高级语言转换为机器代码,为什么我们甚至需要汇编器? 是否有任何汇编级语言,而我们不能为此使用编译器?

If compiler converts high-level language to machine code, why do we even need assembler? Are there any assembly level language and we can't use compiler for that?

推荐答案

相关:

Related: Does a compiler always produce an assembly code? - more about why some compilers do compile only to asm, instead of straight to machine code in some object file format. There are several reasons that compiling to asm instead of machine code makes a compiler's job easier and a compiler more easily portable. But compilers aren't the only reason for asm existing.

为什么我们甚至需要汇编程序?

why do we even need assembler?

许多人不需要懂汇编语言.

Many people don't need to know assembly language.

它的存在是为了让我们可以讨论/分析机器代码,并更轻松地编写/调试编译器.

It exists so we can talk about / analyze machine code, and write/debug compilers more easily.

编译器必须由人类编写. @old_timer指出,在设计新的CPU体系结构时,您总是给操作码和寄存器起个名字,这样您就可以与其他人讨论设计并发布可读的手册.

Compilers have to be written by humans. As @old_timer points out, when designing a new CPU architecture, you always give names to the opcodes and registers so you can talk about the design with other humans, and publish readable manuals.

或者对于OS开发,编译器不能生成某些特殊的特权指令 1 .而且,您不能编写将寄存器保存在纯C中的上下文切换功能.

Or for OS development, some special privileged instructions can't be generated by compilers1. And you can't write a context-switch function that saves registers in pure C.

CPU直接运行机器代码,而不直接运行高级语言,因此计算机安全性/漏洞利用以及任何严重的低级性能分析/单个循环的调整都需要查看CPU运行的指令 >.操作码的助记符名称在思考和编写它们时非常有帮助.与B8+rd imm32(操作码范围)相比, mov r32, imm32 更容易记住并且更具表现力对于该助记符).

CPUs run machine-code, not high-level languages directly, so computer security / exploits, and any serious low-level performance analysis / tuning of single loops require looking at the instructions the CPU is running. Mnemonic names for the opcodes are very helpful in thinking and writing about them. mov r32, imm32 is much easier to remember and more expressive than B8+rd imm32 (the range of opcodes for that mnemonic).

脚注1:除非像MSVC那样,否则您为 __invlpg() ,因此您可以编写没有 inline asm的操作系统. (它们仍然需要一些独立的asm来存储入口点之类的东西,并且可能还需要上下文切换功能.)但是然后这些内在函数仍需要用C命名,因此您最好在asm中对其进行命名.

Footnote 1: Unless like MSVC you create intrinsics for all the special instructions like __invlpg() that OSes need to use, so you can write an OS without inline asm. (They still need some stand-alone asm for stuff like entry points, and probably for a context-switch function.) But then those intrinsics still need names in C so you might as well name them in asm.

我经常使用asm轻松创建要测试的 microbenchmarks 的机器代码.编译器必须创建 efficiency 机器代码,而不仅仅是正确的机器代码,因此,人们经常使用asm来查看各种CPU上的快速运行和不正常运行.

I regularly use asm for easily creating the machine code I want to test for microbenchmarks. A compiler has to create efficient machine code, not just correct machine code, so it's common for humans to play around with asm to see exactly what's fast and what's not on various CPUs.

请参见 http://agner.org/optimize/,以及其他性能链接

See http://agner.org/optimize/, and other performance links in the x86 tag wiki.

例如参见 x86的MOV是否真的可以免费"?为什么我根本无法重现此内容?微融合和寻址模式进行微基准测试的示例,以了解一些快速的方法.

e.g. see Can x86's MOV really be "free"? Why can't I reproduce this at all? and Micro fusion and addressing modes for examples of micro-benchmarking to learn something about what's fast.

请参见用于测试的C ++代码Collat​​z猜想比手写汇编要快-为什么?有关手动编写asm的更多信息,这比我手握gcc或clang发出的速度还要快,即使通过调整C源代码看起来更像asm我想出了.

See C++ code for testing the Collatz conjecture faster than hand-written assembly - why? for more about writing asm by hand that's faster than what I could hand-hold gcc or clang into emitting, even by adjusting the C source to look more like the asm I came up with.

(显然,我必须了解asm才能查看编译器的asm输出并查看如何做得更好.编译器离完美还差很多.有时甚至很远.错过优化的错误是考虑新的优化并建议编译器寻找它们,就asm指令而言,比机器代码要容易得多.)

(And obviously I had to know asm to be able to look at the compiler's asm output and see how to do better. Compilers are far from perfect. Sometimes very far. Missed-optimization bugs are common. To think of new optimizations and suggest that compilers look for them, it's a lot easier to think in terms of asm instructions than machine code.)

有时还会出现错误代码的编译器错误,而验证它们基本上需要查看编译器的输出.

Wrong-code compiler bugs also sometimes happen, and verifying them basically requires looking at the compiler output.

Stack Overflow有几个问题,例如什么更快:a++++a?",答案完全取决于它如何编译成asm,而不取决于源代码级别的语法差异.要了解为什么某些类型的源差异会影响性能,您必须了解代码如何编译为asm.

Stack Overflow has several questions like "what's faster: a++ or ++a?", and the answer completely depends on exactly how it compiles into asm, not on source-level syntax differences. To understand why some kinds of source differences affect performance, you have to understand how code compiles to asm.

例如添加冗余分配可在不使用编译器的情况下加速代码优化. (人们常常没有意识到,有/没有优化的编译不仅是线性加速,而且对未优化的代码进行基准测试基本上毫无意义.未优化的代码存在不同瓶颈...这如果您看一下asm,这是显而易见的.)

e.g. Adding a redundant assignment speeds up code when compiled without optimization. (People often fail to realize that compiling with/without optimization isn't just a linear speedup, and that it's basically pointless to benchmark un-optimized code. Un-optimized code has different bottlenecks... This is obvious if you look at the asm.)

这篇关于为什么在有了编译器时甚至还需要汇编器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆