Code Monkey home page Code Monkey logo

scasm's Introduction

scasm

writing a dynamic x86_64 assembler in Scala

This is the final code for my live coding session at DevoxxFR 2016 I have made with Criteo Labs. The goal of this presentation was to write a dynamic assembler in Scala; or how to create a Scala function from the final x86_64 assembly code.

Have a look at the final code.

Do not ask for the final goal of this: this is more a learning vehicle to abord several interesting topics.

As an example function I wanted to generate at runtime, I decided to go with the add: (Int,Int) => Int function. The assembly code for that is:

mov rax, rdi
add rax, rsi
ret

Which can be read as:

  • Move the content of register rdi to register rax.
  • Add the content of register rsi to register rax and store the result to rax.
  • Return

Why do I use these specific registers for that? Because I was doing this presentation using MacOS on a 64bits intel laptop. So I have to follow the System V x86_64 ABI. If you want to do this on Linux it should be the same. On Windows you probably need to adapt. On 32bits systems it will be more complicated because the parameters are passed on the stack from the begining, so you need more instructions.

Check this about the ABI: http://wiki.osdev.org/System_V_ABI

So the presentation was organized in 2 parts:

  • Finding a way to embed the assembly code into Scala.
  • Making it executable.

Embedding assembly into Scala code

Actually this part is pretty easy. After having defined all the required data structures to represent Registers, Operands and Instructions, I have used a custom StringContext interpolation, and Scala parser combinator.

At the end of this part I was able to write something like:

val add: Seq[Instr] =
  asm"""
    mov rax, rdi
    add rax, rsi
    ret
  """

Making it executable

The first step is to generate machine code from the asm representation. For that I have just written a minimal assembler supporting the required instructions/access modes.

Useful resources for that:

To check the result of this assembler you can compare with a real existing assembler. For example using nasm, I have created this asm file:

[bits 64]

mov rax, rdi
add rax, rsi
ret

And I have compared the output with mine by running:

$ nasm add.asm && hexdump add

Then I had to load this code in memory and to make it executable. For that I have used sun.misc.Unsafe to allocate an aligned page of memory (see the hack to get an aligned page). And then I have used JNA to make a wrapper to the libc allowing me to call int mprotect(void *addr, size_t len, int prot);.

At this point the code was loaded in memory and marked as executable. I have used JNA again to get a native function from the pointer. At the end using Scala implicit conversion I was able to cast it to a proper Scala function type, allowing me to write:

val add: (Int,Int) => Int = nativeFunction(
  asm"""
    mov rax, rdi
    add rax, rsi
    ret
  """
)

println(add(3,2))

A real Scala function created from assembly code => CHECK

scasm's People

Contributors

guillaumebort avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.