64ビットシステムで32ビットアセンブリ
1983 ワード
『Professional Assembly Language』(Richard Blum著)の第4章のサンプルプログラムを読むと、アセンブリでC言語ライブラリ関数printfを使用するデモがありましたが、このコードをテストする際にいくつかの問題に遭遇しました.まず私のシステム環境を説明します.Linux Mint 18.3 Cinnamon 64 bitを実行しています.
コードテストで発生した問題は、64ビットシステムで32ビットアセンブリが行われているため、実際には互換性のない問題である.この問題を回避するために、32ビットアセンブリのアセンブリ(as)と接続(ld)を本で正常に行うように指導するには、32ビット関数ライブラリを含むパッケージをインストールし、端末で実行する必要がある.
まずアセンブリソースファイルcpuid 2を開く.s,最初の行にコード「.code 32」を追加
端末でアセンブリを実行する:
cpuid2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter/lib/ld-linux.so.2, not stripped
これで、コードテストに成功し、プログラムは正常に実行できます.
互換性の問題
コードテストで発生した問題は、64ビットシステムで32ビットアセンブリが行われているため、実際には互換性のない問題である.この問題を回避するために、32ビットアセンブリのアセンブリ(as)と接続(ld)を本で正常に行うように指導するには、32ビット関数ライブラリを含むパッケージをインストールし、端末で実行する必要がある.
生成32-bitプログラムの指定
まずアセンブリソースファイルcpuid 2を開く.s,最初の行にコード「.code 32」を追加
# cpuid2.s view the CPUID vendor id string using C library calls
.code32
.section .data
output:
.asciz "the processor vendor id is '%s'
"
.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
端末でアセンブリを実行する:
sudo apt install lib32z1 lib32ncurses5 g++-multilib libc6-dev-i386
32ビットターゲットファイルcpuid 2を生成する.o次に接続操作を実行する:as --32 -o cpuid2.o cpuid2.s
linuxで実行可能なプログラムcpuid 2を生成し、ファイルタイプld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o cpuid2 -lc cpuid2.o
の結果を表示することができる: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'
"
.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