楽しむ為のアセンブラとして続けてきた "ForFun(x86_32)" の最後は、Linux上でgccを使ったアセンブラプログラミングを体験してみます。
今回はglibcのprintf()を使った定番の"Hello, World"をGNU asで作ってみます。直接システムコールを呼び出したり、libcを使わないアセンブラプログラミングについては、本記事末尾の参考図書の項をご覧下さい。
今回はglibcを使い、エントリポイントについてもglibcにお任せ、つまりmain()関数を用意します。
gccの場合、cdecl規約ではシンボル名を修飾しないので、"main", "printf"とそのまま書きます。
Web上にサンプルも豊富です。今回は次のようなソースになりました。
hello1.s:
.text .global main main: push %ebp mov %esp, %ebp push $hellomsg call printf mov $2, %eax mov %ebp, %esp pop %ebp ret .data hellomsg: .string "Hello, *nix World!\n"
コンパイルしてみます。今回はgccツールチェインの力で楽をしてみます。
$ as -o hello1.o hello1.s $ gcc -o hello1 hello1.o
あるいはいきなり、
$ gcc -o hello1 hello1.s
でもOKです。
実行してみます。
$ ./hello1 Hello, *nix World! $ echo $? 2
今回はgccツールチェインの力を借り、ライブラリもディストリビューション提供のglibcを使ったので、非常に簡潔なソースになりました。以下のCソースをアセンブラで書いたのと事実上変わりません。
hello.c:
#include <stdio.h> int main() { printf("Hello, *nix World!\n"); return 2; }
本格的に踏み込んで、Linuxの提供するシステムコール(割り込み)を直接呼んでみたり、glibcを使わずにldコマンドで手動リンクしたりといった高度な技法については以下の参考図書をご覧下さい。
参考図書:
"HACK#25 glibc を使わないで Hello World を書く"で、システムコール呼び出し+glibcを使わない"Hello, World"の作り方が紹介されています。
最後にまとめです。今回は gcc + glibc の力を借りて "Hello, World!" の GNU as 版を作ってみました。
本シリーズでは 16bit DOS/16bit BIOS/32bit Win32API/32bit linux と、様々な環境でアセンブラプログラミングを体験してきました。
特にx86のリアルモードの16bitアセンブラにウェイトをおいて紹介してきました。もしMBR以降のOSのブートに関わるアセンブラプログラミングと出会った時に、本シリーズでの体験を活かして頂ければ幸いです。
またそのような機会が無くとも、暇な時にお手持ちの環境で、手軽にx86アセンブラプログラミングを楽しんでみて下さい。