centos 64位系统编译TinyHelloWorld.c
程序员的自我修养中,有一段是通过内嵌汇编来完成一个HelloWorld程序,这段汇编是32位的,在64位的机器上直接编译就会出问题。
- 源代码
/*
*TinyHelloWorld.c
*/
char* str = "Hello World!\n";
void print(){
asm( "movl $13,%%edx \n\t"
"movl %0,%%ecx \n\t"
"movl $0,%%ebx \n\t"
"movl $4,%%eax \n\t"
"int $0x80 \n\t"
::"r"(str):"edx","ecx","ebx");
}
void exit() {
asm( "movl $42,%ebx \n\t"
"movl $1,%eax \n\t"
"int $0x80 \n\t");
}
void nomain() {
print();
exit();
}
- 编译过程
gcc -c -fno-builtin -m32 TinyHelloWorld.c
-
-fno-builtin 不使用内置函数
-
-static 使用静态链接的方式来链接程序
-
-e nomain 表示该程序的入口函数为nomain
-
-o TinyHelloWorld 表示指定输出可执行文件名为TinyHelloWorld
原因就是64位的系统不能编译32位的目标文件
解决方案:
用-m32强制用32位API编译,就可以编译通过
gcc -c -fno-builtin -m32 TinyHelloWorld.c
- 使用ld链接脚本
TinyHelloWOrld.lds
ENTRY(nomain)
SECTIONS
{
. = 0x0804800 + SIZEOF_HEADERS;
tinytext : { * (.text) *(.data) *(.rodata) }
/DISCARD/ : { *(.coment) }
}
- 链接报错
ld -static -e nomain -o TinyHelloWorld TinyHelloWorld.o
链接的时候加上"-m elf_i386"
ld -static -m elf_i386 -e nomain -o TinyHelloWorld TinyHelloWorld.o