  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の２つの例：
     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の２つの例：

  アセンブラ.028から優れたサンプルをpieter de jong氏が出しました。

  例１)    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

  とコンパイルします。

  例２) 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

