assembly & linux jan wagemakers, janw@mail.dma.be 21/07/1997 伊佐治 哲, isaji@mxu.meshnet.or.jp 24 jan 1998 (訳注:この文書はhttp://bewoner.dma.be/JanW/からのものです。以下 「webページ」はこのurlを指しています)。これは"x86互換マシン/linuxオペ レーティングシステム"でアセンブリプログラミング言語を使った試みについ て書かれたwebページです。 ______________________________________________________________________ 目次 1. 更新履歴 2. アセンブリ & DOS 3. アセンブリ & Linux 4. アセンブリ & Linux - 結果 - 4.1 NASMの例をみてみましょう: 4.2 gasの2つの例: 4.3 GASにマクロを追加する: 4.4 ncursesを使う 5. 連絡情報 ______________________________________________________________________ 1. 更新履歴 このテストを行っているうちにいくつか興味深いことに気づきました。こ のwebページに追加していきたいと思います。以下、新しい情報をみつけやす くするために更新履歴を書きます。 xx/06/1997 : start linux & assembler ホームページ 05/07/1997 : change h.2.1.3. (add macro's to gas) 21/07/1997 : change h.2.1.4. (ncurses (sat_color.s)) 2. アセンブリ & DOS アセンブリ...わけあってアセンブリ言語でプログラミングすることが気に 入っています。dos環境下で、長いことアセンブリを使ってきました。この試 みによってdkopieが生まれました。dkopie は 2mといった拡張フォーマットで コピーできるようにしたディスクコピープログラムです。 2mについての情報は以下を参照して下さい: the homepage of ciriaco garcia de celis dkopieの最新版は現在dkopie v3.0です。 http://www.simtel.net/pub/simtelnet/msdos/diskutil/dkopie30.zip からダ ウンロードできます。 3. アセンブリ & Linux DOSは現在のコンピュータでは力不足です。しかしWindowsを使う気にもなりま せん。そこでLinuxを使っているのですが、このOSのおかげでとても幸せにな りました :-)。 UNIX & Linux では標準的なプログラミング言語は C や C++ です。これは多くの機能を持っていて他のコンピュータシステムにも移植され ています。しかしアセンブリが使いたいのでLinuxとアセンブリの魅力には抵 抗できません。以下、この試みについての結果をまとめました。いろいろな情 報を提供してくれた fidonet (assembler.028, 80xxx, linux.b, linux) の方 々に感謝いたします。 4. アセンブリ & Linux - 結果 - Linuxアセンブリプログラムを書くときそこには多くの可能性があります。は じめにどのアセンブラを使うか選べます。GAS(AS)を使うのがよいでしょ う。gasはほとんどのLinuxディストリビューションの標準となっているアセン ブラです。 gasの欠点はgasがAT&T-syntaxを使っていることです。これは Intel-syntaxと大きく違っています。 DOSユーザーはほとんど がIntel-syntaxを使っています。 AT&T-syntaxについてのより詳細な情報は infoファイルにあります。こ のinfoファイルをhtmlフォーマットに変換しました。 Intel互換のsyntaxを参照する時はnasmでプログラムを書くことができます。 4.1. NASMの例をみてみましょう: from the 80xxx-fidonet-area : = deze bewaar ik : asm =================================================keepit= from : james vahn 17-apr-97 15:20:22 1:346/15.1 to : jan wagemakers 2:292/8133.23 subj : nasm & linux =======================================================================rem_asm= * 80xxx からの引用 jw> デモがありますが、見ている範囲ではcプログラムから呼び出すように jw> 書かれています。nasmとlinuxで 100% アセンブリプログラムをどのように jw> 書くのか知りたいです。 バグフィックスされたnasm-0.94を使って、ソースを以下のようにアセンブルします。 nasm -f elf hello.asm gcc hello.o -o hello strip hello 学ぶことがたくさんあります :-) ______________________________________________________________________ ;-------------nasm's standalone hello-world.asm for linux -------- section .text extern puts global main main: push dword msg ;stash the location of msg on the stack. call puts ;call the 'puts' routine (libc?) add esp, byte 4 ;clean the stack? ret ;exit. msg: db "hello world!",0 ______________________________________________________________________ --- timed 1.01 * origin: james vahn (jvahn@short.circuit.com) (1:346/15.1) =============================================================================== この例ではputsの呼び出しは画面にテキストを表示するのに使われま す。putsは cからのもので、Linuxでロードされるライブラリの標準表示で す。しかしアセンブリでこれを行う方法もあります。interrupts です。 Linuxカーネルの今後のバージョンで変更されるかもしれないのでこの割り込 み (interrupts)を使うのはお奨めしません。 4.2. gasの2つの例: アセンブラ.028から優れたサンプルをpieter de jong氏が出しました。 例1) putsの呼び出しを使った例 ______________________________________________________________________ .text message: .ascii "hello world!\0" .align 4 .globl main main: pushl %ebp movl %esp,%ebp #call ___main pushl $message call puts addl $4,%esp xorl %eax,%eax movl %ebp,%esp popl %ebp ret ______________________________________________________________________ として、 as hello.s -o hello.o gcc hello.o -o hello とコンパイルします。 例2) int 80hを使う ______________________________________________________________________ .text message: .ascii "hello, world!\12\0" .align 4 .globl _hw _hw: movl $4, %eax movl $1, %ebx movl $message, %ecx movl $15, %edx int $0x80 movl $1, %eax movl $0, %ebx int $0x80 ______________________________________________________________________ として、 as hello.s -o hello.o ld hello.o -e _hw -o hello (_hw = エントリポイント) とコンパイルします。 4.3. GASにマクロを追加する: changed on : 5 Jul 1997 マクロを使うことによってプログラミングの複雑さをすくなくできます。ある ドキュメントで、GASはマクロを解釈できずアセンブリでマクロを使うに はGASPを使わねばならないということを読みました。 しかし.. いくつかテストしてみたりGNU-C infoファイルを読んだところ GAS(as)を使ってアセンブリプログラムにマクロを加えることができることを 発見しました。以下、私が行ったテストを紹介します。GAS と マクロ の可能 性を試みています (訳注:dummy.dummyというファイルがあるかチェックする プログラムです)。 test_fopen.sのソース: ______________________________________________________________________ .include "include.asm" .globl main main: _print hallo # タイトル表示 _open bestand mode # ファイル'dummy.dummy'を開く cmp $0,%eax # Success? je file_error # だめ。エラーメッセージの表示 _close %eax # ファイルを閉じる _print bestaat # 'exist'と表示 jmp einde # プログラム終了 file_error: _print bestaat_niet # 'doesn't exist'と表示する einde: ret # The End ;-) hallo: .string "Test Linux Program ;-) \n" bestaat: .string "The file dummy.dummy exists..." bestaat_niet: .string "The file dummy.dummy doesn't exist..." bestand: .string "dummy.dummy" mode: .string "r" .END ______________________________________________________________________ include.asm ______________________________________________________________________ .MACRO _print message # start _print message pushl $\message call puts addl $4,%esp # end _print message .ENDM .MACRO _open file mode # start _open ファイルモード pushl %ebp movl %esp,%ebp pushl $\mode pushl $\file call fopen addl $8,%esp movl %eax,-4(%ebp) # %eax = ファイルハンドル # - %eax = 0 ならファイルはない # - %eax >< 0 %eax ならファイルハンドル popl %ebp # end _open ファイルモード .ENDM .MACRO _close filehandle # start _close ファイルハンドル pushl \filehandle call fclose addl $4,%esp # end _close ファイルハンドル .ENDM ______________________________________________________________________ として、これを as test_fopen.s -o test_fopen.o gcc test_fopen.o -o test_fopen のようにコンパイルします。 4.4. ncursesを使う 1997年7月21日 変更: Ncurses はテキストベースのLinuxプログラムを書くときに使う関数のライブ ラリです。 以下、ピュアなアセンブリプログラムからncurseesをどのように呼び出すか見 るためにサンプルプログラムを挙げます。ちゃんとしたものではないかもしれ ませんが動作をみるにはよいと思います :-) 。 sat_color.s ______________________________________________________________________ .include "/home/jan/assembler/include/ncurses.asm" .globl main main: _initscr _start_color _init_pair $1,$2,$4 _init_pair $2,$0,$6 _init_pair $3,$3,$4 _init_pair $4,$4,$4 # Hide the flashing cursor call cls # clear screen/init colors. _use_pair $0x00000200 # 00 00(NORMAL) 02(PAIR) 00 _locate $1,$0 _printw $titel _locate $46,$0 _printw $pd _use_pair $0x00200100 # 00 20(BOLD) 01(PAIR) 00 _locate $32,$12 _printw $world _use_pair $0x00200300 # 00 20(BOLD) 03(PAIR) 00 movl $0,%esi lus: movb tabel(%esi),%dl # %dl = X(%esi) incl %esi movb tabel(%esi),%cl # %cl = Y(%esi) incl %esi cmpb $242,%cl jne n242_1 movl $0,%esi jmp lus n242_1: movl %esi,%edi redo: movb tabel(%edi),%dh # %dh = X(%esi + 1) incl %edi movb tabel(%edi),%ch # %ch = Y(%esi + 1) cmpb $242,%ch jne n242_2 movl $0,%edi jmp redo n242_2: movl $leeg,%ebp call print_item movl $linux,%ebp movb %ch,%cl movb %dh,%dl call print_item pushl $160000 # C : usleep(....); call usleep # Wait-loop addl $4,%esp _refresh jmp lus _endwin ret print_item: pushal movzbl %cl,%eax movzbl %dl,%ebx _locate %ebx,%eax _printw %ebp popal ret cls: _use_pair $0x00000200 # 00 00(NORMAL) 02(PAIR) 00 # Color of the first line movb $0,%cl movb $0,%dl cls_lus: movl $chr32,%ebp call print_item incb %dl cmpb $79,%dl jna cls_lus pushal _use_pair $0x00000400 # 00 00(NORMAL) 04(PAIR) 00 # Color of the rest of the screen popal xorb %dl,%dl incb %cl cmpb $25,%cl jna cls_lus ret linux: .string "Linux" leeg: .string " " chr32: .string " " world: .string "World Domination" titel: .string "sat_color.s - 1997 Jan Wagemakers -" pd: .string "Donated to the Public Domain :-)" tabel: .include "cirkel.dat" .byte 242,242 .END ______________________________________________________________________ (訳注:先頭のncurses.asmのインクルードディレクトリは適当に変更して下さ い) cirkel.dat ______________________________________________________________________ .byte 72 , 12 .byte 71 , 13 .byte 69 , 15 .byte 66 , 17 .byte 62 , 18 .byte 56 , 20 .byte 51 , 21 .byte 44 , 21 .byte 38 , 21 .byte 31 , 21 .byte 24 , 21 .byte 18 , 20 .byte 13 , 19 .byte 8 , 17 .byte 5 , 16 .byte 3 , 14 .byte 2 , 12 .byte 2 , 10 .byte 3 , 8 .byte 6 , 7 .byte 10 , 5 .byte 15 , 4 .byte 20 , 3 .byte 27 , 2 .byte 33 , 2 .byte 40 , 2 .byte 47 , 2 .byte 53 , 3 .byte 59 , 4 .byte 63 , 5 .byte 67 , 7 .byte 70 , 8 .byte 71 , 10 ______________________________________________________________________ /home/jan/assembler/include/ncurses.asm ______________________________________________________________________ # ncurses.asm - donated to the public domain by Jan Wagemakers - # derived of the following C-program # #include # # int main(void) # { # initscr(); /* cursesライブラリの初期化 */ # move(10, 2); /* カーソルを X: 2, Y: 10 に置く */ # printw("Hello, World !"); /* 表示するもの */ # refresh(); /* 物理画面に "Hello, World !" を置く */ # getch(); /* キーが押されるのを待つ */ # endwin(); /* deinit the curses libraries. */ # return 0; # } # # Cについてよく知らないので以下は違うこともあります。 # 修正するときはためらわずやって下さい。 # ncursesを使って画面に何か書きたいという時は以下のマクロを呼び出します。 # 1. _initscr # 2. _locate x y (x,y = 画面の座標) # 3. _printw message # 4. _refresh # 5. _endwin (winの終り.... なにかいい響きですね ;-) .MACRO _initscr # start _initscr call initscr # end _initscr .ENDM .MACRO _locate x y # start _locate x y pushl \x pushl \y movl stdscr,%eax pushl %eax call wmove addl $12,%esp # end _locate x y .ENDM .MACRO _printw message # start _print message pushl \message call printw addl $4,%esp # end _printw message .ENDM .MACRO _refresh # start _refresh movl stdscr,%eax pushl %eax call wrefresh addl $4,%esp # end _refresh .ENDM .MACRO _endwin # start _endwin call endwin # end _endwin .ENDM # Colors と ncurses. (15/07/97) # - After _initscr , call _start_color # - Init with _init_pair a color-pair. # - With _use_pair select a color-pair. .MACRO _start_color # start _start_color call start_color # end _start_color .ENDM .MACRO _init_pair pair foreground background # start _init_pair pushl \background pushl \foreground pushl \pair call init_pair addl $12,%esp # end _init_pair .ENDM .MACRO _use_pair pair # start _use_pair movl \pair,%eax # | | %ah | %al | # %eax = xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx # | | # | | # | +----> 使いたいカラーペア(color-pair)番号 # +-------------> 00 = ノーマル , 20 = BOLD pushl %eax movl stdscr,%eax pushl %eax call wattr_on addl $8,%esp #end _use_pair .ENDM ______________________________________________________________________ as sat_color.s -o sat_color.o gcc sat_color.o -o sat_color -lncurses とコンパイルし、./sat_colorで実行します(訳注:このプログラムを実行する と青い背景の画面中央に緑文字で「World Domination」、その周りを黄色文字 「Linux」がぐるぐる回るデモが見れます。color_xtermなどで実行してみて下 さい)。 5. 連絡情報 アセンブリに関する情報を募集しています :-) 。 Jan Wagemakers Internet : JanW@mail.dma.be Fidonet : 2:292/854.19