Search code examples
assemblyx86gnu-assembler

Source code for adding new GNU assembler x86 instruction and recompile


I am trying to figure out which file I need to modify in binutils project so I can add a new x86 instruction mov2 which will be exact copy of mov. Searching source folder resulted hundred of result yet still I couldnt find any file containing instruction references.

Thank you


Solution

  • As @Jester mentioned file needs to be modified is opcodes/i386-opc.tbl also I had to bother him on IRC for further details but he was kind enough to guide me. I might note that I was only able to generate on binutils v2.25, I believe later branches start using different solution, might be related with "make run-cgen" target but its study for another day:)

    Here are the steps I have followed:

    Create temp dirs, one for build and one for binaries:

    $mkdir -pv /tmp/{instruction-test,tools}
    $cd /tmp/instruction-test/
    

    clone the binutils repo or you can download straight from gnu ftp:

    $git clone http://sourceware.org/git/binutils-gdb.git
    

    switch to branch:

    $cd binutils/
    $git checkout binutils-2_25
    

    pre-build project:

    $mkdir -v build
    $cd build
    $../configure --prefix=/tmp/tools  --with-sysroot=/tmp/tools  --with-lib-path=/tmp/tools/lib  --target=x86_64-custom-linux-gnu  --disable-nls  --disable-werror
    
    $make clean
    $time make -s -j XX > make.log || { echo "can not make project, please check logs installation aborted" ; exit 1; }
    

    now add mov2 instructions as exact copy of mov

    $cd ../opcodes
    $cat i386-opc.tbl | egrep -e '^mov,' | sed 's/mov/mov2/g' >> i386-opc.tbl
    

    now you can pause here and look what we have added:

    $git diff i386-opc.tbl
    

    now we need to update i386 opcode table as well:

    $cd ../build/opcodes
    $make i386-gen
    $./i386-gen --srcdir=$(pwd)/../../opcodes
    

    now we can rebuild and install into /tmp/tools:

    $cd ..
    $time make -s > make.log
    $make -s install > install.log
    

    time to test! Here is small example with new instructions:

    $cat > /tmp/hello << EOF
            .global _start
    
            .text
    _start:
            # write(1, message, 13)
            mov2     $1, %rax                # system call 1 is write
            mov2     $1, %rdi                # file handle 1 is stdout
            mov2     $message, %rsi          # address of string to output
            mov2     $13, %rdx               # number of bytes
            syscall                         # invoke operating system to do the write
    
            # exit(0)
            mov2     $60, %rax               # system call 60 is exit
            xor     %rdi, %rdi              # we want return code 0
            syscall                         # invoke operating system to exit
    message:
            .ascii  "Hello, world\n"
    EOF
    $cd /tmp/tools/bin
    $./x86_64-custom-linux-gnu-as -o /tmp/hello.o /tmp/hello
    $ld /tmp/hello.o -o /tmp/hello.bin
    $cd /tmp/
    $./hello.bin
    

    now you should be able to see output:

    Hello, world
    

    If you hit issues I suspect it would be related with cat/EOF command, you can simply try with your own file. As I mentioned this is not up to date solution and I had trouble running i386-gen on later branches which I believe managed by cgen? or maybe I needed to deal with stdin used here but I didnt have much time