Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/antonioberna/call-assembly-from-c
Simple project that combine the power of Assembly language with the power of C language
https://github.com/antonioberna/call-assembly-from-c
aarch64 armv8-a assembly c calling-conventions intel raspberry-pi-3 x86
Last synced: about 12 hours ago
JSON representation
Simple project that combine the power of Assembly language with the power of C language
- Host: GitHub
- URL: https://github.com/antonioberna/call-assembly-from-c
- Owner: AntonioBerna
- License: mit
- Created: 2024-05-29T01:12:39.000Z (9 months ago)
- Default Branch: master
- Last Pushed: 2024-06-12T02:38:27.000Z (8 months ago)
- Last Synced: 2024-12-19T10:36:04.038Z (about 2 months ago)
- Topics: aarch64, armv8-a, assembly, c, calling-conventions, intel, raspberry-pi-3, x86
- Language: Assembly
- Homepage:
- Size: 10.7 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# How to call Assembly functions from C
## Introduction
This is a simple project that combine the power of `Assembly` language with the power of `C` language. In this project I have create a basic calculator with the four fundamental operations, namely sum, subtract, multiplication and division. Obviously this is not a large-scale production project, but it represents a tool for educational purposes. In fact, in this project three versions of `Assembly` language were implemented and used: `AT&T`, `Intel` and `ARM`.
> [!WARNING]
> This code has only been tested on `Manjaro Linux` (for `AT&T Assembly` and `Intel Assembly`) and `Raspberry Pi 3 Model B` (for `ARM Assembly` based on `aarch64` run on `Raspbian` operating system). If you experience problems using other operating systems, such as `Windows` or `macOS`, make sure you have the appropriate skills or risk damaging your equipment.## Mini docs
Download the repository to your computer using the following command:
```shell
git clone https://github.com/AntonioBerna/call-assembly-from-c.git
```once we are inside the project folder we can use one of the following programs:
```shell
./build.sh ATT
# or
./build.sh intel
# or
./build.sh arm
# or
./build.sh clean
```in fact, leaving aside the last command which is used to eliminate the final executables, the first two commands represent the type of `Assembly` that is used and therefore combined with the `C` language. Obviously we are not talking about architecture, but only and exclusively about syntax preferences. In fact, the dear `AT&T Assembly` has for each instruction it uses a syntax of the type:
```assembly
istrX %source, %destination
```where `X` represents the number of bytes of registers that will be used as source and destination. In particular we can choose between `b` (1 byte = 8 bits), `l` (2 bytes = 16 bits), `w` (4 bytes = 32 bits) and `q` (8 bytes = 64 bits). This type of `Assembly` is a classic but can sometimes be cumbersome. In fact, for this very reason many people prefer to use or read the `Intel Assembly`:
```assembly
istr source, destination
```As we can see, by not having to specify the number of bytes/bits, by not having to specify the `%` symbol and by not having to specify the `$` symbol for immediate values, this syntax is simpler and more pleasant.
Finally the syntax of `ARM Assembly` is very different from the previous ones and appears, in the simplest case, as follows:
```assembly
istr destination, operand1, operand2
```in fact we note the presence of 3 parameters. However, in this type of `Assembly` we can also use 2 parameters, based on the type of instruction we want to use.
Once the command has been chosen, the executable file will be created inside the `build` directory. Therefore we can run our code using the following command:
```shell
./build/ATT-calculator
# or
./build/intel-calculator
# or
./build/arm-calculator
```getting the following message:
```shell
Usage: ./build/ATT-calculator [add|sub|mul|div|test] [x] [y]
# or
Usage: ./build/intel-calculator [add|sub|mul|div|test] [x] [y]
# or
Usage: ./build/arm-calculator [add|sub|mul|div|test] [x] [y]
```Then simply follow the instructions in the message obtained to use the program correctly.
> [!NOTE]
> I would like to point out that there is also the `test` option which allows us to execute a function to test some very simple operations.## How to read Assembly code
The `System V Application Binary Interface (ABI)` is a set of conventions used on Unix-like operating systems, such as `Linux` and `Solaris`, to define how functions should be called and how data should be passed between functions in a compiled program. `System V ABI` calling conventions for 64 bit systems include:
- Return Register: The return value of a function is stored in the `RAX` register.
- Parameter passing: The first six integers or pointers are passed into registers `RDI`, `RSI`, `RDX`, `RCX`, `R8` and `R9`. The other parameters are passed onto the `stack`, in order from left to right.
- Saving registers: The called function must save the `RBX`, `RSP`, `RBP`, `R12`, `R13`, `R14`, and `R15` registers if it uses them and restore them before returning control to the caller.
- Stack alignment: The `stack` must always be aligned to a multiple of 16 bytes at the start of a function.
- Data Structure Conventions: Data structures smaller than 16 bytes and unions are passed into registers if possible. Data structures larger than 16 bytes are passed by reference.
- Management of local variables: Local variables are usually allocated on the `stack`, moving the stack pointer (`RSP`).
- Handling function calls: The calling function is responsible for cleaning up the `stack` after the call, removing passed parameters.
These conventions are designed to maximize the efficiency and interoperability of programs on operating systems that adopt the `System V ABI` for 64 bit architectures. They ensure that functions can communicate consistently and that code can be effectively optimized by the compiler.