简体   繁体   中英

Mixing assembler code with c/c++

Why is assembly language code often needed along with C/C++ ?

What can't be done in C/C++, which is possible when assembly language code is mixed?

I have some source code of some 3D computer games. There are a lot of assembler code in use.

Things that pop to mind, in no particular order:

  • Special instructions. In an embedded application, I need to invalidate the cache after a DMA transfer has filled the memory buffer. The only way to do that on an SH-4 CPU is to execute a special instruction, so inline assembly (or a free-standing assembly function) is the only way to go.

  • Optimizations. Once upon a time, it was common for compilers to not know every trick that was possible to do. In some of those cases, it was worth the effort to replace an inner loop with a hand-crafted version. On the kinds of CPUs you find in small embedded systems (think 8051, PIC, and so forth) it can be valuable to push inner loops into assembly. I will emphasize that for modern processors with pipelines, multi-issue execution, extensive caching and more, it is often exceptionally difficult for hand coding to even approach the capabilities of the optimizer.

  • Interrupt handling. In an embedded application it is often needed to catch system events such as interrupts and exceptions. It is often the case that the first few instructions executed by an interrupt have special responsibilities and the only way to guarantee that the right things happen is to write the outer layer of a handler in assembly. For example, on a ColdFire (or any descendant of the 68000) only the very first instruction is guaranteed to execute. To prevent nested interrupts, that instruction must modify the interrupt priority level to mask out the priority of the current interrupt.

  • Certain portions of an OS kernel. For example, task switching requires that the execution state (at least most registers including PC and stack pointer) be saved for the current task and the state loaded for the new task. Fiddling with execution state of the CPU is well outside of the feature set of the language, but can be wrapped in a small amount of assembly code in a way that allows the rest of the kernel to be written in C or C++.

Edit: I've touched up the wording about optimization. Let me emphasize that for targets with large user populations and well supported compilers with decent optimization, it is highly unlikely that an assembly coder can beat the performance of the optimizer.

Before attempting, start by careful profiling to determine where the bottlenecks really lie. With that information in hand, examine assumptions and algorithms carefully, because the best optimization of all is usually to find a better way to handle the larger picture. Then, if all else fails, isolate the bottleneck in a test case, benchmark it carefully, and begin tweaking in assembly.

In the past, compilers used to be pretty poor at optimizing for a particular architecture, and architectures used to be simpler. Now the reverse is true. These days, it's pretty hard for a human to write better assembly than an optimizing compiler, for deeply-pipelined, branch-predicting processors. And so you won't see it much. What there is will be short, and highly targeted.

In short, you probably won't need to do this. If you think you do, profile your code to make sure you've identified a hotspot - don't optimize something just because it's slow, if you're only spending 0.1% of your execution time there. See if you can improve your design or algorithm. If you don't find any improvement there, or if you need functionality not exposed by your higher-level language, look into hand-coding assembly.

There are certain things that can only be done in assembler and cannot be done in C/C++.

These include:

  1. generating software interrupts (SWI or INT instructions)
  2. Use of instructions like SWP for creating mutexes
  3. specialist coporcessor instructions (such as those needed to program the MMU and manage RAM caches)
  4. Access to carry and overflow flags.

You may also be able to optimize code better in assembler than C/C++ (eg memcpy on Android is written in assembler)

可能存在编译器无法生成的新指令,或编译器执行错误的操作,或者您可能需要直接控制CPU。

Why is assembly language code often needed along with C/C++ ?

Competitive advantage. Like, if you are writing software for the (soon-to-be) #1 gaming company in the world.

What can't be done in C/C++, which is possible when assembly language code is mixed?

Nothing, unless some absolute performance level is needed, say, X frames per second or Y billions of polygons per second.

Edit: based on other replies, it seems the consensus is that embedded systems (iPhone, Android etc) have hardware accelerators that certainly require the use of assembly.

I have some source code of some 3D computer games. There are a lot of assembler code in use.

They are either written in the 80's-90's, or they are used sparingly (maybe 1% - 5% of total source code) inside a game engine.

Edit: to this date, compiler auto-vectorization quality is still poor. So, you may see programs that contain vectorization intrinsics, and since it's not really much different from writing in actual assembly (most intrinsics have one-one mapping to assembly instructions) some folks might just decide to write in assembly.

Update:

According to anecdotal evidence, RollerCoaster Tycoon is written in 99% assembly.
http://www.chrissawyergames.com/faq3.htm

Why is assembly language code often needed along with C/C++ ?needed along with C/C++ ?

It isn't

What can't be done in C/C++, which is possible when assembly language code is mixed?

Accessing system registers or IO ports on the CPU. Accessing BIOS functions. Using specialized instructions that doesn't map directly to the programming language, eg SIMD instructions. Provide optimized code that's better than the compiler produces.

The two first points you usually don't need unless you're writing an operating system, or code running without an operatiing system.

Modern CPUs are quite complex, and you'll be hard pressed to find people that actually can write assembly than what the compiler produces. Many compilers come with libraries giving you access to more advanced features, like SIMD instructions, so nowadays you often don't need to fall back to assembly for that.

One more thing worth mentioning is:

  • C & C++ do not provide any convenient way to setup stack frames when one needs to implement a binary level interop with a script language - or to implement some kind of support for closures.

程序集可以是任何编译器在某些情况下可以生成的最佳程序。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM