64位处理器进行32位at&t汇编-编译与连接

首先说明我使用的电脑型号: Linux ThinkPad-Edge-E440 3.16.0-34-generic #47-Ubuntu SMP  x86_64 x86_64 x86_64 GNU/Linux


当at&t汇编源程序中包含c库函数的调用时,直接编译会出错

例如:

#cpuid_c.s Sample program to extract the processor Vendor ID

.section .data
output:
    .asciz "The processor Vendor ID is '%s'\n"
.section .bss
    .lcomm buffer, 12

.section .text
.globl _start
_start:
    movl $0, %eax
    cpuid
movl $buffer, %edi
movl %ebx, (%edi)
movl %edx, 4(%edi)
movl %ecx, 8(%edi)
pushl $buffer
pushl $output
call printf
addl $8, %esp
pushl $0
call exit


这个源文件中包含printf和exit两个c函数调用

解释: man as

得到

          Target i386 options:
          [--32|--x32|--64] [-n]
          [-march=CPU[+EXTENSION...]] [-mtune=CPU]

这个“--32”参数说明as命令要将源程序编译为i386处理器兼容的32位目标文件


下面时连接了,当然直接连接也是不行的

ThinkPad-Edge-E440:~/assembly$ ld -o cpuid_c cpuid_c.o
ld: i386 architecture of input file `cpuid_c.o' is incompatible with i386:x86-64 output
cpuid_c.o: In function `_start':
(.text+0x1f): undefined reference to `printf'
cpuid_c.o: In function `_start':
(.text+0x29): undefined reference to `exit'

这就需要连接c函数库文件,ubuntu系统的c函数库文件是libc.so.6。但是在/usr/lib路径下找不到libc.so.6。因此我们需要建立一个软链接:

ThinkPad-Edge-E440:/usr/lib$ sudo ln -sv /lib/i386-linux-gnu/libc.so.6 libc.so
‘libc.so’ -> ‘/lib/i386-linux-gnu/libc.so.6’

除此之外我们还需要指定运行时加载动态库的程序:dynamic-linker /lib/ld-linux.so.2

连接命令: ld -m elf32_i386 -dynamic-linker /lib/ld-linux.so.2 -o helloworld helloworld.o -lc

说明:-m elf32_i386

"-m" 参数是说明连接的程序仿真elf32可执行文件,这也是必须的。

man ld

摘录得:

-m emulation
           Emulate the emulation linker.  You can list the available emulations with the --verbose or -V options.

           If the -m option is not used, the emulation is taken from the "LDEMULATION" environment variable, if that is defined.

           Otherwise, the default emulation depends upon how the linker was configured.


如此连接后程序就正常了。连接后的程序也是32位的。

实例程序出自《professional assembly language》


你可能感兴趣的:(ubuntu)