在x86-64位系统中编译运行x86-32的c程序

 实验环境:

[root@ht6 test]# uname -a
Linux ht6.node 3.10.0-1160.62.1.el7.x86_64 #1 SMP Tue Apr 5 16:57:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
[root@ht6 test]# cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)
[root@ht6 test]# lscpu
Architecture:          x86_64  //64位
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    1
Core(s) per socket:    4
Socket(s):             2
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 63
Model name:            Intel(R) Xeon(R) CPU E5-2660 v3 @ 2.60GHz
Stepping:              2
CPU MHz:               2593.993
BogoMIPS:              5187.98
Hypervisor vendor:     VMware
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              25600K
NUMA node0 CPU(s):     0-7

[root@ht6 test]# getconf LONG_BIT
64  //64位

[root@ht6 test]# arch 
x86_64

  在x86-64位系统中编译运行x86-32的c程序(寄存器为64位)

//需要安装兼容包
 [root@ht6 asm]# yum -y install glibc-devel.i686 glibc-devel ibstdc++-devel.i686


代码test.c

#include <stdio.h>
int add(int a, int b)
{
        int result = a + b;
        return result;
}

int main(int argc)
{
        int answer;
        answer = add(111, 222);
}

实验: 编译32位程序

 [root@ht6 asm]# gcc -m32 -S test.c  //生成汇编 test.s   -m32参数指定编译为32位程序
 [root@ht6 asm]# gcc -m32 -o output32 test.c   //编译出可执行 outpu32程序
生成汇编文件如下命令:
gcc -m32 -S test.c #AT&T风格语法,-m32指定32位汇编指令
[root@ht6 asm]# vim test.s

        .file   "test.c"
        .text
        .globl  bar
        .type   bar, @function
bar:
.LFB0:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        subl    $16, %esp
        movl    $555, -4(%ebp)
        movl    12(%ebp), %eax
        movl    8(%ebp), %edx
        addl    %edx, %eax
        movl    %eax, -8(%ebp)
        leave
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
.LFE0:
        .size   bar, .-bar
        .globl  foo
        .type   foo, @function
foo:
.LFB1:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
四个阶段完成整个的编译

 

 

 

gdb测试:
  [root@ht6 asm]# gdb -tui -q ./output32
   (gdb) b main
   (gdb)r
 (gdb)layout regs  ### 命令执行显示效果如下,
注意寄存器红色名称:

 查看文件格式

[root@ht6 asm]# file output32 
output32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked 
(uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=8e9ffb90783e7855fec3c49d2ff55a7e469d4423,
not stripped

反汇编结果只留下我感兴趣的,其他删掉了:(AT&T语法) - 

[root@ht6 asm]# objdump -d output32 
output32:     file format elf32-i386  //格式
Disassembly of section .init:
0804828c <_init>:
 804828c:    53                       push   %ebx   //第一行,53代表操作码(指令解析器层次)
 804828d:    83 ec 08                 sub    $0x8,%esp
 8048290:    e8 7b 00 00 00           call   8048310 <__x86.get_pc_thunk.bx>
 8048295:    81 c3 6b 1d 00 00        add    $0x1d6b,%ebx
 804829b:    8b 83 fc ff ff ff        mov    -0x4(%ebx),%eax
 80482a1:    85 c0                    test   %eax,%eax
 80482a3:    74 05                    je     80482aa <_init+0x1e>
 80482a5:    e8 26 00 00 00           call   80482d0 <.plt.got>
 80482aa:    83 c4 08                 add    $0x8,%esp
 80482ad:    5b                       pop    %ebx
 80482ae:    c3                       ret    

Disassembly of section .text:

080482e0 <_start>:
 80482e0:    31 ed                    xor    %ebp,%ebp
 80482e2:    5e                       pop    %esi
 80482e3:    89 e1                    mov    %esp,%ecx
 80482e5:    83 e4 f0                 and    $0xfffffff0,%esp
 80482e8:    50                       push   %eax
 80482e9:    54                       push   %esp
 80482ea:    52                       push   %edx
 80482eb:    68 90 84 04 08           push   $0x8048490
 80482f0:    68 20 84 04 08           push   $0x8048420
 80482f5:    51                       push   %ecx
 80482f6:    56                       push   %esi
 80482f7:    68 13 84 04 08           push   $0x8048413
 80482fc:    e8 bf ff ff ff           call   80482c0 <__libc_start_main@plt>
 8048301:    f4                       hlt    
 8048302:    66 90                    xchg   %ax,%ax
 8048304:    66 90                    xchg   %ax,%ax
 8048306:    66 90                    xchg   %ax,%ax
 8048308:    66 90                    xchg   %ax,%ax
 804830a:    66 90                    xchg   %ax,%ax
 804830c:    66 90                    xchg   %ax,%ax
 804830e:    66 90                    xchg   %ax,%ax

080483dd <bar>:
 80483dd:    55                       push   %ebp
 80483de:    89 e5                    mov    %esp,%ebp
 80483e0:    83 ec 10                 sub    $0x10,%esp
 80483e3:    c7 45 fc 2b 02 00 00     movl   $0x22b,-0x4(%ebp)
 80483ea:    8b 45 0c                 mov    0xc(%ebp),%eax
 80483ed:    8b 55 08                 mov    0x8(%ebp),%edx
 80483f0:    01 d0                    add    %edx,%eax
 80483f2:    89 45 f8                 mov    %eax,-0x8(%ebp)
 80483f5:    c9                       leave  
 80483f6:    c3                       ret    

080483f7 <foo>:
 80483f7:    55                       push   %ebp
 80483f8:    89 e5                    mov    %esp,%ebp
 80483fa:    83 ec 08                 sub    $0x8,%esp
 80483fd:    c7 44 24 04 de 00 00     movl   $0xde,0x4(%esp)
 8048404:    00 
 8048405:    c7 04 24 6f 00 00 00     movl   $0x6f,(%esp)
 804840c:    e8 cc ff ff ff           call   80483dd <bar>
 8048411:    c9                       leave  
 8048412:    c3                       ret    

08048413 <main>:
 8048413:    55                       push   %ebp
 8048414:    89 e5                    mov    %esp,%ebp
 8048416:    e8 dc ff ff ff           call   80483f7 <foo>  //栈帧的起始地址,main+3=8048416
 804841b:    5d                       pop    %ebp
 804841c:    c3                       ret    
 804841d:    66 90                    xchg   %ax,%ax
 804841f:    90                       nop

 objdump -x 显示文件头信息

[root@ht6 asm]# objdump -x  output32 
output32:     file format elf32-i386
output32
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x080482e0

Program Header:
//.....忽略
objdump:支持的目标: 
elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 a.out-i386-linux
pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little
elf32-big plugin srec symbolsrec verilog tekhex binary ihex objdump:支持的体系结构:
i386 i386:x86-64 i386:x64-32 i8086 i386:intel i386:x86-64:intel
i386:x64-32:intel i386:nacl i386:x86-64:nacl i386:x64-32:nacl iamcu iamcu:intel l1om l1om:intel
k1om k1om:intel plugin
posted @ 2023-03-08 20:31  jinzi  阅读(0)  评论(0)    收藏  举报