意外と早くできたアセンブラで"Hello World!"

CのHelloWorldプログラムのgccによるアセンブリ言語版を見て,アセンブラで"Hello World!"を出すとこまで行くのはかなり時間を要するかと思ったけれどもいきなり次がこれだった.

; dispstr.asm
 bits 16
 org  0x100

 mov  ah, 9
 mov  dx, msg
 int  0x21

 mov  ah, 0x4C
 mov  al, 0
 int  0x21

 msg db "Hello World!$"

アセンブルして実行すると

D:\asmwork>nasm -f bin dispstr.asm -o dispstr.com

D:\asmwork>dispstr.com
Hello World!

実に簡単にできてしまう.

しかしアセンブラに"文字列"という概念があったのは驚いた.C言語だとchar配列になってるのにね.というかアセンブラってレジスタに値代入、計算、計算、Hoge、Fugaってやつだと思ってた.標準出力に文字列を出すとか,意外と高機能."int 21h"はOSの機能を利用する,いわゆる「システムコール」らしい.まあアセンブリ言語機械語とは言え,OSの上で動くわけだからそうなのか.

あまりにも簡単に終わってしまったので,ちょっと弄ってみる.

"org 0x100"を抜かしてみたら

D:\asmwork>dispstr.com
"Kミ"Vミ"ミ" ,

んんん.ナイスな壊れっぷり.さすがアセンブラ

復習とまとめ

  • "bits 16"で16ビットプログラムであることを宣言
  • "org 0x100"で0x100以降のアドレスにコードをロード
  • 数値の前に"0x"を付けるか数値の後に"h"を付けると16進数という意味に
  • "org 0x100"と"mov ah, 9"はとりあえずおまじない
  • "mov dx, msg"はmsgのアドレスをDXに代入
  • AHに9が入っている状態で"int 0x21"を呼ぶとDXに入っているアドレスから始まる文字列を標準出力
  • "$"は文字列の終端を示す
  • "\n"とか書いても改行はされずにそのまま文字として出力される

  • "mov ah, 9"の9や2は16進数なのか何なのか."0x9"と書いても動きは同じ.

結局アセンブリ言語も,テキストファイルを「アセンブラ」が解析(パース)してバイナリに変換しているだけな訳だから,要するにアセンブラプログラマが対話するためのものに過ぎないわけか.