@@ -371,7 +371,7 @@ Tested on a30ed0f047523ff2368d421ee2cce0800682c44e + 1.
Have you ever felt that a single `inc` instruction was not enough? Really? Me too!
So let's hack the link:https://en.wikipedia.org/wiki/GNU_Assembler[GNU GAS assembler], which is part of link:https://en.wikipedia.org/wiki/GNU_Binutils[GNU Binutils], to add a new shiny version of `inc` called... `myinc`!
So let's hack the <<gnu-gas-assembler>>, which is part of link:https://en.wikipedia.org/wiki/GNU_Binutils[GNU Binutils], to add a new shiny version of `inc` called... `myinc`!
GCC uses GNU GAS as its backend, so we will test out new mnemonic with an inline assembly test program: link:userland/arch/x86_64/binutils_hack.c[], which is just a copy of link:userland/arch/x86_64/asm_hello.c[] but with `myinc` instead of `inc`.
@@ -11622,6 +11622,18 @@ Other infrastructure sanity checks that you might want to look into include:
Much like ADD for non-SIMD, start learning SIMD instructions by looking at the integer and floating point SIMD ADD instructions of each ISA:
@@ -11673,7 +11685,7 @@ The C standard library infrastructure is implemented in the following files:
Unlike most our other assembly examples, which use the C standard library for portability, examples under `freestanding/` directories don't link to the C standard library.
As a result, those examples cannot do IO portably, and so they make raw system calls and only be run on one given OS, e.g. Linux: <<linux-system-calls>>
As a result, those examples cannot do IO portably, and so they make raw system calls and only be run on one given OS, e.g. Linux: <<linux-system-calls>>.
Such executables are called freestanding because they don't execute the glibc initialization code, but rather start directly on our custom hand written assembly.
@@ -11703,7 +11715,7 @@ Examples under `arch/<arch>/c/` directories show to how use inline assembly from
** link:userland/arch/aarch64/c/inc.c[]
** link:userland/arch/aarch64/c/multiline.cpp[]
==== Inline assembly register variables
==== GCC inline assembly register variables
Used notably in some of the <<linux-system-calls>> setups:
@@ -11715,7 +11727,11 @@ In x86, makes it possible to access variables not exposed with the one letter re
In arm, it is the only way to achieve this effect: https://stackoverflow.com/questions/10831792/how-to-use-specific-register-in-arm-inline-assembler
==== Inline assembly scratch registers
This feature notably useful for making system calls from C, see: <<linux-system-calls>>.
link:https://en.wikipedia.org/wiki/GNU_Assembler[GNU GAS] is the default assembler used by GDB, and therefore it completely dominates in Linux.
Let's see how may bytes go into each data type:
The Linux kernel in particular uses GNU GAS assembly extensively for the arch specific parts under `arch/`.
==== GNU GAS assembler comments
In this tutorial, we use exclusively C Preprocessor `/**/` comments because:
* they are the same for all archs
* we are already stuck to the C Preprocessor because GNU GAS macros are unusable so we need `#define`
* mixing `#` GNU GAS comments and `#define` is a bad idea ;-)
But just in case you want to suffer, see this full explanation of GNU GAS comments: https://stackoverflow.com/questions/15663280/how-to-make-the-gnu-assembler-use-a-slash-for-comments/51991349#51991349
Examples:
* link:userland/arch/arm/comments.S[]
* link:userland/arch/aarch64/comments.S[]
==== GNU GAS assembler immediates
Summary:
* x86 always dollar `$` everywhere.
* ARM: can use either `#`, `$` or nothing depending on v7 vs v8 and <<gnu-gas-assembler-arm-unified-syntax,`.syntax unified`>>.
They are very similar, but unified is the new and better one, which we use in this tutorial.
Unfortunately, for backwards compatibility, GNU AS 2.31.1 and GCC 8.2.0 still use `.syntax divided` by default.
The concept of unified assembly is mentioned in ARM's official assembler documentation: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0473c/BABJIHGJ.html and is often called Unified Assembly Language (UAL).
Some of the differences include:
* `#` is optional in unified syntax int literals, see <<gnu-gas-assembler-immediates>>
* many mnemonics changed:
** most of them are condition code position changes, e.g. `andseq` vs `andeqs`: https://stackoverflow.com/questions/51184921/wierd-gcc-behaviour-with-arm-assembler-andseq-instruction
** but there are some more drastic ones, e.g. `swi` vs `svc`: https://stackoverflow.com/questions/8459279/are-arm-instructuons-swi-and-svc-exactly-same-thing/54078731#54078731
* cannot have implicit destination with shift, see: <<shift-suffixes>>
===== GNU GAS assembler ARM .n and .w suffixes
When reading disassembly, many instructions have either a `.n` or `.w` suffix.
`.n` means narrow, and stands for the Thumb encoding of an instructions, while `.w` means wide and stands for the ARM encoding.
Arch general getting started at: <<userland-assembly>>.
TODO
=== Introduction to the ARM architecture
The link:https://en.wikipedia.org/wiki/ARM_architecture[ARM architecture] is has been used on the vast majority of mobile phones in the 2010's, and on a large fraction of micro controllers.
It competes with <<x86-userland-assembly>> because its implementations are designed for low power consumption, which is a major requirement of the cell phone market.
ARM is generally considered a RISC instruction set, although there are some more complex instructions which would not generally be classified as purely RISC.
ARM is developed by the British funded company ARM Holdings: https://en.wikipedia.org/wiki/Arm_Holdings which originated as a joint venture between Acorn Computers, Apple and VLSI Technology in 1990.
ARM Holdings was bought by the Japanese giant SoftBank in 2016.
==== Free ARM implementations
The ARM instruction set is itself protected by patents / copyright / whatever, and you have to pay ARM Holdings a licence to implement it, even if you are creating your own custom Verilog code.
ARM has already sued people in the past for implementing ARM ISA: http://www.eetimes.com/author.asp?section_id=36&doc_id=1287452
Asanovic joked that the shortest unit of time is not the moment between a traffic light turning green in New York City and the cab driver behind the first vehicle blowing the horn; it’s someone announcing that they have created an open-source, ARM-compatible core and receiving a “cease and desist” letter from a law firm representing ARM.
____
This licensing however does have the following fairness to it: ARM Holdings invents a lot of money in making a great open source software environment for the ARM ISA, so it is only natural that it should be able to get some money from hardware manufacturers for using their ISA.
Patents for very old ISAs however have expired, Amber is one implementation of those: https://en.wikipedia.org/wiki/Amber_%28processor_core%29 TODO does it have any application?
Generally, it is mostly large companies that implement the CPUs themselves. For example, the link:https://en.wikipedia.org/wiki/Apple_A12[Apple A12 chip], which is used in iPhones, has verilog designs:
____
The A12 features an Apple-designed 64-bit ARMv8.3-A six-core CPU, with two high-performance cores running at 2.49 GHz called Vortex and four energy-efficient cores called Tempest.
____
ARM designed CPUs however are mostly called `Coretx-A<id>`: https://en.wikipedia.org/wiki/List_of_applications_of_ARM_cores Vortex and Tempest are Apple designed ones.
The official manuals were stored in http://infocenter.arm.com but as of 2017 they started to slowly move to link:https://developer.arm.com[].
Each revision of a document has a "ARM DDI" unique document identifier.
The "ARM Architecture Reference Manuals" are the official canonical ISA documentation document. In this repository, we always reference the following revisions:
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.