X86 assembler on Linux (linkage with C)

About this article

There are two main ways to program in assembler. One is to create the entire program with assembler, and the other is to write only some functions with assembler. The former is not realistic considering the low readability of the assembler. That is why the latter becomes the mainstream. Maintainability and high effective speed can be achieved by writing some functions in assembler and others in C.

Necessary tools

This article assumes a Linux environment. Assembler is highly environment dependent and will only work on Linux. Please prepare the following software in the Linux environment.

Creating a program

Write the C program main.c below and the assembler program add.asm with an editor and save them.


#include <cstdio>
extern int asm_add(int a, int b);

int main()
    int a, b;
    a = 1;
    b = 2;
    int ans = asm_add(a, b);
    printf("%d\n", ans);

    return 0;


section .text
global _sm_add
    enter 0,0
    mov eax, edi
    mov ebx, esi
    add eax, ebx

Compile main.c to generate an object file.

gcc -c -o main.o main.c

 Compile add.asm to generate an object file.

#### **` nasm -g -f elf64 -o add.o add.asm `**

Link the generated object file.

gcc -o add -lc -g main.o add.o -o add

 Now you have the executable add.
 When executed
``` 3 ```
 Is displayed on the screen.

# C program side commentary
 I will explain the source of C. Very simple code. First of all, the function `` `int add (int a, int b)` `` is declared in extern.
 In assembly files, header files cannot handle connections between objects as you normally would in C. Therefore, declare it with extern and specify the external link.
 The other parts are the same as a normal C program.
 Similarly, in C ++, you can call functions created in assembler.

# Assembler side commentary
 Since it is a short code, it is explained line by line.

#### **` section .text Means the beginning of the code..Besides text.data(Declaration of initialized data)、.bss(Declaration of uninitialized data)There is a section of, but it is omitted in this code.`**

global _asm_addMarker_asm_Add is specified globally so that it can be referenced from other codes.

Is a marker. Below this is the function asm_The body of add.

``` enter 0,0 ```Is an instruction to build a stack frame. The stack frame is the storage destination of the data expanded in the memory. It stores the variables used in the function and the addresses of the instructions to return after the function ends.

mov eax, edi mov ebx, esi

 Moves the arguments a and b to general-purpose registers. In the Linux environment, function arguments are stored in registers and passed. This is to reduce the frequency of memory access and speed up the process. There is a one-to-one decision as to which register the data for which argument of the function is stored. The correspondence table is shown below.

 | edi |First argument|
 | esi |Second argument|
 | edx |Third argument|
 | ecx |Fourth argument|
 | r8d |Fifth argument|
 | r9d |Sixth argument|

 From the 7th argument, it is exchanged via the stack. However, considering execution speed and readability, you probably don't need more than the 7th argument.

add eax, ebx

 The contents of ebx and the contents of eax are added. In the Linux environment, the value of eax is used as the return value of the function.
``` leave
ret ```
```leave```Releases the stack.```enter```It is an instruction paired with.``` ret ```Then, it returns to the address of the function caller pushed to the stack by the call instruction.

# At the end
 You can now call the assembly from c. This method allows the compiler to manually perform optimizations that are difficult to do automatically.
**Happy Hacking!!**

# References
* "System V Application Binary Interface AMD64 Architecture Processor Supplement"   
 * th0x4c Note: [GDB] Check the Linux X86-64 calling Convention with Gdb

* Guide to Assembly Language Programming in Linux

 ↓ ↓ Any comments will be encouraging ↓ ↓

Recommended Posts

X86 assembler on Linux (linkage with C)
[C] [python] Read with AquesTalk on Linux
Using X11 with ubuntu18.04 (C)
Set up Docker on Oracle Linux (7.x) with Vagrant
Test Python with Miniconda on OS X and Linux with travis-ci
Install Mecab on Linux (CentOS) with brew
Installing PIL with Python 3.x on macOS
Run Linux on ARM architecture with QEMU
Compiling the Linux kernel (Linux 5.x on Ubuntu 20.04)
Communicate with I2C devices in Linux C
Linux x memo
Set up golang with goenv on GNU / Linux
[Note] Install wxPython 3.x on Linux Mint (Ubuntu)
Start a process with a scheduling policy on Linux
Organize files on Windows with Linux commands-using WSL-
Put Python 2.7.x on Mac OSX 10.15.5 with pyenv
Build Oracle Database 19c on Oracle Linux 8.3 (DB Build Part 2)
Install PHP 7 series on Amazon Linux 2 with Amazon Linux Extras
Run Kali Linux on Windows with GUI (without VirtualBox)
How to use C216 Audio Controller on Arch Linux
Yum command to access MySQL with Python 3 on Linux
How to install caffe on OS X with macports
Make a breakpoint on the c layer with python
Compactly build an Oracle database (19c) on Linux on VirtualBox
Install PyQt5 with homebrew on Mac OS X Marvericks (10.9.2)
Easy build of C ++ code with CMake on Docker
Daemonizing processes on Linux
Container-like # 1 made with C
Debugging C / C ++ with gdb
jblas on Arch Linux
Linux kernel release 5.x (2/4)
Linux (WSL) on Windows
NAT router on Linux
Linux (Lubuntu) with OneMix3S
Container-like # 2 made with C
Linux kernel release 5.x (3/4)
linux with termux app
Develop .NET on Linux
Wake on lan on Linux
Monitor traffic on Linux
Update vscode on linux
Linux kernel release 5.x (4/4)
Try NeosVR on Linux
Check capacity on Linux
Linux kernel release 5.x (1/4)
LiveUSB creation on Linux
Linux operation on Win10
Problems with Chrome after suspending on Linux desktop KDE + Nvidia
Intuitive password management with aws ssm on Mac / Linux alias
USB device programming with native C on Android 5.0 and above
BASIC and C and assembler speed comparison and optimization play with IchigoJam
Learn "x86 architecture learned with your own emulator" with Manjaro (Linux)
Build Python3 for Windows 10 on ARM with Visual Studio 2019 (x86) on Windows 10 on ARM
How to install Theano on Mac OS X with homebrew
Get the host name of the host PC with Docker on Linux