x86 assembly on a 64 bit Linux Part 1 - itzjac/cpplearning GitHub Wiki

To start learning x86 assembly language or to improve your coding skills with assembly language, is crucial learning the tools.

I will guide you to write and generate x86 assembly instructions (32-bit instructions) using a 64 bit operating system with a very unoptimized but fast compiler.

First part we create a framework to compile 32-bit applications and generate 32-bit asm instructions.

Second part will analyze the x86 asm generated by TCC (Tiny C Compiler) when compiling a C file and how to create executables with assembly language.

Third part debugging asm using gdb.

Requirements

  • Basic linux usage and terminal
  • Configuring, Compiling, linking C programs

The following tutorials applies for Ubuntu 20.04 x64, but very similar process can be applied to a Win or OSx operating system.

Top end compilers like g++, cl, clang usually contain vast amount of optimizations to help programs run faster, which means the asm code generated is more complex and convoluted.

We are picking Tiny C Compiler (a.k.a. TCC), a very unoptimized compiler that generates programs with asm instructions that are simpler to read and closer to that of academic texts or tutorials.

Ubuntu configuration

Using the ubuntu terminal and with sudo powers.

To enable 32 bit capabilities in a x64 machine, it is necessary to install all the 32 bit libraries version (e.i. i386).

  • Enable gcc to compile to different targets gcc-multilib

    #apt install gcc-multilib

  • C runtime library for 32 bit applications

    #apt install libc6-dev:i386

  • Install TCC

    #apt install tcc

Validate you have the necessary C run time libraries properly installed, list the crt*.o files

#dpkg -S /usr/lib/i386-linux-gnu; dpkg -S /usr/lib/x86_64-linux-gnu

Should list the location on your system where both libraries, 64 and 32-bit, should be installed.

Compiling C files

Assume any arbitrary C code with a main function, example1.c

#include <stdlib.h>

int sub(int x, int y)
{
     return 666*x +y;
}

int main(int argc, char** argv)
{
    int a;
    if (argc > 2)
    {
       a = atoi(argv[1]);
    }
    return sub(argc, a);
}

to compile and generate the 32 bit version, notice -m32 will compile for 32 bit mode

#tcc -m32 -g -o example1 example1.c

Upon file examination of the executable file "example1"

#file example1

Should report an ELF 32-bit executable 1603231704536

DONE!

Optional - Compiling the compiler

Tiny C Compiler

Finally, will show you how to compile TCC source code on the x64 Ubuntu machine, please download the source files (http://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27.tar.bz2).

Locate the tcc files extracted, open a terminal. 4 compile options are needed to generate the cross compile code, if your triplet library is located in /usr/lib/i386-linux-gnu, the command should contain

#./configure --enable-cross --cpu=i386 --triplet=/usr/lib/i386-linux-gnu --ctrprefix=/usr/lib/i386-linux-gnu

Then compile and install

#make
#make install

Now you can compile following the instructions in the section Compiling C files.

NOTE: you might need to include in the compilation options, to use your own compiled libs and includes.

Continue Part 2

⚠️ **GitHub.com Fallback** ⚠️