在64位虚拟机上编译C程序为32位的可执行文件

操作系统CentOS-7-x86_64

系统里应该默认是没有安装gcc的,但是有gcc的安装包,可以用yum list|grep gcc查看下。

[root@localhost code]# yum list|grep gcc
libgcc.x86_64                             4.8.5-44.el7                 @anaconda
compat-gcc-44.x86_64                      4.4.7-8.el7                  base     
compat-gcc-44-c++.x86_64                  4.4.7-8.el7                  base     
compat-gcc-44-gfortran.x86_64             4.4.7-8.el7                  base     
gcc.x86_64                                4.8.5-44.el7                 base     
gcc-c++.x86_64                            4.8.5-44.el7                 base     
gcc-gfortran.x86_64                       4.8.5-44.el7                 base     
gcc-gnat.x86_64                           4.8.5-44.el7                 base     
gcc-go.x86_64                             4.8.5-44.el7                 base     
gcc-objc.x86_64                           4.8.5-44.el7                 base     
gcc-objc++.x86_64                         4.8.5-44.el7                 base     
gcc-plugin-devel.x86_64                   4.8.5-44.el7                 base     
libgcc.i686                               4.8.5-44.el7                 base     
relaxngcc.noarch                          1.12-6.el7                   base     
relaxngcc-javadoc.noarch                  1.12-6.el7                   base 

然后进行安装

[root@localhost code]# yum install gcc.x86_64
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.tuna.tsinghua.edu.cn
 * extras: mirrors.tuna.tsinghua.edu.cn
 * updates: mirrors.tuna.tsinghua.edu.cn

安装结束后,可以进行汇编一个C程序

int g(int x)
{
  return x+3;
}

int f(int x)
{
  return g(x);
}

int main(void)
{
  return f(8)+1;
}
[root@localhost code]# gcc -S -o main.s main.c -m32
[root@localhost code]# ls
a.out  main.c  main.s

但是如果是需要进行连接(link)的程序,如果想要看到完整的汇编语言程序,最好是对.o可执行文件进行反编译。用objdump可以进行反编译。

[root@localhost code]# objdump -S a.out

a.out:     文件格式 elf64-x86-64


Disassembly of section .init:

00000000004003e0 <_init>:
  4003e0:	48 83 ec 08          	sub    $0x8,%rsp
  4003e4:	48 8b 05 0d 0c 20 00 	mov    0x200c0d(%rip),%rax        # 600ff8 <__gmon_start__>
  4003eb:	48 85 c0             	test   %rax,%rax
  4003ee:	74 05                	je     4003f5 <_init+0x15>
  4003f0:	e8 3b 00 00 00       	callq  400430 <__gmon_start__@plt>
  4003f5:	48 83 c4 08          	add    $0x8,%rsp
  4003f9:	c3                   	retq   

由于centOS是运行在64位处理器上的,所以反编译后是64位的汇编程序,而我比较习惯看32位的汇编程序,怎么办呢?

首先在编译c为.o文件时,就需要生成32位处理器的可执行文件,于是

[root@localhost code]# gcc -g test.c -m32
In file included from /usr/include/features.h:399:0,
                 from /usr/include/stdio.h:27,
                 from test.c:1:
/usr/include/gnu/stubs.h:7:27: 致命错误:gnu/stubs-32.h:没有那个文件或目录
 # include 
                           ^
编译中断。

编译报错,说找不到这个库函数,上网查了查说需要安装支持32位处理器的C lib库: glibc-devel.i686

[root@localhost gnu]# ls
libc-version.h  lib-names.h  stubs-64.h  stubs.h
[root@localhost gnu]# yum install glibc-devel.i686
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.bupt.edu.cn
 * extras: mirrors.huaweicloud.com
 * updates: mirrors.huaweicloud.com

安装后,有stubs-32.h文件

[root@localhost gnu]# ls
libc-version.h  lib-names.h  stubs-32.h  stubs-64.h  stubs.h

继续编译还是报错

[root@localhost code]# gcc -g test.c -m32
/usr/bin/ld: 当搜索用于 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so 时跳过不兼容的 -lgcc_s 
/usr/bin/ld: 找不到 -lgcc_s
collect2: 错误:ld 返回 1

有查了查,说需要安装libgcc.i686

[root@localhost code]# yum install libgcc.i686
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.tuna.tsinghua.edu.cn
 * extras: mirrors.tuna.tsinghua.edu.cn
 * updates: mirrors.tuna.tsinghua.edu.cn

安装成功后,编译32位成功,反编译成功

[root@localhost code]# gcc -g test.c -m32
[root@localhost code]# ls
a.out  main.c  main.s  main.s.clean  test.c
[root@localhost code]# objdump -S a.out 

a.out:     文件格式 elf32-i386


Disassembly of section .init:

080482ac <_init>:
 80482ac:	53                   	push   %ebx
 80482ad:	83 ec 08             	sub    $0x8,%esp
 80482b0:	e8 8b 00 00 00       	call   8048340 <__x86.get_pc_thunk.bx>
 80482b5:	81 c3 4b 1d 00 00    	add    $0x1d4b,%ebx

你可能感兴趣的:(linux)