在64位系统中进行32位汇编

在阅读《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

你可能感兴趣的:(在64位系统中进行32位汇编)