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.
We can write assembly program code inside c language program. In such case, all the assembly code must be placed inside asm{} block.
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.
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With