Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixing C and Assembly files

Tags:

c++

c

x86

gcc

assembly

I want to use a naked function in my C++ program using g++. Unfortunately g++, unlike VC++, does not support naked functions and the only way to manage this is to write your own assembly code in a separate file and link with your C++ files. I tried to find some good tutorial for x86 to mix assembly and C/C++ files but couldn't find any good one.

Kindly let me know if you know about any. Note that I'm not asking about inline assembly but linking C and assembly files and ways to declare extern variables of C in assembly and vice versa besides using them in either C or assembly, and also ways to link the C and asm files using Makefile.

like image 838
MetallicPriest Avatar asked Nov 08 '11 17:11

MetallicPriest


People also ask

Can you run assembly in C?

We can write assembly program code inside c language program. In such case, all the assembly code must be placed inside asm{} block.

Does C compile down to assembly?

c is being compiled without any additional links or files, so the program will be converted into an executable by itself. Alas, for the grand finale, let's run the full shebang (no computing reference intended here), gcc main. c without any options, to preprocess, compile, assemble, and link the program all at once.


2 Answers

In C++ file:

extern "C" void foo(); // Stop name mangling games

int main() {
  foo();
}

in "naked" asm file, for x86:

# modified from http://asm.sourceforge.net/howto/hello.html

.text                   # section declaration
    .global foo

foo:

# write our string to stdout

    movl    $len,%edx   # third argument: message length
    movl    $msg,%ecx   # second argument: pointer to message to write
    movl    $1,%ebx     # first argument: file handle (stdout)
    movl    $4,%eax     # system call number (sys_write)
    int $0x80       # call kernel

# and exit

    movl    $0,%ebx     # first argument: exit code
    movl    $1,%eax     # system call number (sys_exit)
    int $0x80       # call kernel

.data                   # section declaration

msg:
    .ascii  "Hello, world!\n"   # our dear string
    len = . - msg           # length of our dear string

Compile, assemble and link (with g++ rather than ld because it's much easier to do it that way for C++) and run:

ajw@rapunzel:/tmp > g++ -Wall -Wextra test.cc -c -o test.o
ajw@rapunzel:/tmp > as -o asm.o asm.S
ajw@rapunzel:/tmp > g++ test.o asm.o
ajw@rapunzel:/tmp > ./a.out
Hello, world!

If you want to pass arguments to your function or return anything you need to respect the calling conventions.

like image 67
Flexo Avatar answered Sep 29 '22 11:09

Flexo


Here's an example of a trick to achieve the "naked function" effect.

#include <stdio.h>

extern "C" int naked_func ();

static void
dummy ()
{
  __asm__ __volatile__
    (
     "  .global naked_func\n"
     "naked_func:\n"
     "  movq    $3141569, %rax\n"
     "  ret\n"
     );
}

int
main ()
{
  printf ("%d\n", naked_func ());
  return 0;
}
like image 32
chill Avatar answered Sep 29 '22 11:09

chill