有时候需要在C/C++里调用汇编代码,但又不想写内联asm,就需要一些特殊手段了。
在64位编译32位的代码
划重点,我用的是64位的Centos7。Ubuntu同理,但是安装的库不太一样,下面会提到。
报错/usr/include/gnu/stubs.h:7:27: 致命错误:gnu/stubs-32.h:没有那个文件或目录
,这代表需要安装32位的C和C++库:
sudo yum install glibc-devel.i686
sudo yum install libstdc++-devel.i686
如果是64位的Ubuntu,那么需要安装这些库:
# C
sudo apt-get install gcc-multilib
# C++(感谢cgy指出)
sudo apt-get install g++-multilb
如果顺利,最后这一套是能跑起来的:
nasm -f elf32 func.asm -o func.o
gcc -m32 test.c func.o -o hello
./hello
如果要用C++,首先会报错对‘maxofthree(int, int, int)’未定义的引用
(这个maxofthree是自定义的函数,没有什么特殊含义),这意味着需要使用extern "C"声明:
extern "C"
{
int maxofthree(int, int, int);
}
然后重复之前的命令。此时会报错对‘std::cout’未定义的引用
,这意味着需要换成g++:
g++ -m32 test.cpp func.o -o hello
原因
在64位的情况下,参数通过rdi,rsi,rdx,rcx,r8,r9寄存器传递(超出后通过栈rsp传递)。而在32位的情况下,参数是直接通过栈传递的,可以直接通过esp获取参数。