当我们有编译器时,为什么我们甚至需要汇编器? [英] Why do we even need assembler when we have compiler?

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

问题描述

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

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?

推荐答案

相关:编译器是否总是生成汇编代码? - 更多关于为什么某些编译器确实只编译为 asm,而不是直接编译为某些目标文件格式的机器代码.编译为 asm 而不是机器代码有几个原因使编译器的工作更容易并且编译器更容易移植.但是编译器并不是 asm 存在的唯一原因.

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.

或者对于操作系统开发,编译器无法生成一些特殊的特权指令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 正在运行的指令.操作码的助记名称对于思考和书写它们非常有帮助.mov r32, imm32B8+rd 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() 是操作系统需要用到的,所以你可以写一个没有的操作系统内联 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 测试的机器代码.编译器必须创建高效机器代码,而不仅仅是正确的机器代码,因此人类经常使用 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/ 和其他性能链接 在 x86 标签 wiki 中.

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

例如请参阅 x86 的 MOV 真的可以吗免费"?为什么我根本无法重现这个?微融合和寻址模式a> 获取微基准测试的示例,以了解什么是快速的.

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.

例如添加冗余分配可加快代码编译时的速度优化.(人们常常没有意识到,有/没有优化的编译不仅仅是线性加速,对未优化的代码进行基准测试基本上没有意义.未优化的代码有不同的瓶颈......这如果你看一下汇编就很明显了.)

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天全站免登陆