在阅读《Professional Assembly Language》(Richard Blum 著)第四章的示例程序时,其中有演示在汇编中使用C语言库函数--printf,但我在测试这段代码时遇到了一些问题。
首先说明我的系统环境,运行的是 Linux Mint 18.3 Cinnamon 64 bit。
兼容问题
代码测试中所遇到的问题究其原因,是在64位系统中进行了32位汇编,事实上就是不兼容的问题,为了避免这个问题,让汇32位编代码的汇编(as)和连接(ld)按书中指导正常进行,需要安装一些包含32位函数库的软件包,在终端运行:
sudo apt install lib32z1 lib32ncurses5 g++-multilib libc6-dev-i386
指定生成32-bit程序
首先打开汇编源码文件cpuid2.s,在首行添加代码 ".code32"
# cpuid2.s view the CPUID vendor id string using C library calls
.code32
.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
在终端运行汇编器:
as --32 -o cpuid2.o cpuid2.s
生成32位目标文件cpuid2.o
然后执行连接操作:
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o cpuid2 -lc cpuid2.o
生成linux下可执行程序cpuid2,可以查看文件类型
file cpuid2
结果为:
cpuid2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped
至此,代码测试成功,程序可以正常运行。
编写64-bit汇编代码
# cpuid64.s using 64-bit assembly language
# view the CPUID vendor id string using C library calls
.section .data
output:
.asciz "the processor vendor id is '%s'\n"
.section .bss
.lcomm buffer,12
.section .text
.globl _start
_start:
movq $0, %rax
cpuid
movq $buffer, %rdi
movq %rbx, (%rdi)
movq %rdx, 4(%rdi)
movq %rcx, 8(%rdi)
movq $buffer, %rsi
movq $output, %rdi
movq $0, %rax
call printf
addq $8, %rsp
pushq $0
call exit