アンケートご協力のお願いgihyo.jpでは,2010年度に向けて豪華プレゼントが当たる読者属性アンケートを実施しております。ご協力ください。

gihyo.jp » DEVELOPER STAGE » 連載 » アンティーク・アセンブラ~Antique Assembler » 第3回 もしも“if”なら

アンティーク・アセンブラ~Antique Assembler

第3回 もしも“if”なら

たとえば,C言語でif/elseやswitch,for,while/do-while,条件演算("cond ? v1 : v2" 形式の記述)が使用できないとしたら,有用なプログラムを書くことはできるでしょうか?

実行時に与えられるデータに関わらず,常に一定の手順でしか処理できないとしたら,ソフトウェアの有用性は非常に限定されたものになるでしょう。

今回は,アセンブラにおいて“if”を実現するための,条件判定に関して説明します。

状態フラグ

一般的な CPU アーキテクチャでは,演算等の命令を実行した際に,実行結果に応じて状態が変化するフラグを備えています。

この「実行結果に応じて状態が変化するフラグ」(以下「状態フラグ」)は,特殊なレジスタ上の一部のビットが割り当てられていることが多く,このレジスタは多くの場合,“Condition Code Register”(CCR)や“State Register”(SR)等と呼ばれますが,Intel 80x86アーキテクチャの場合はそのものズバリのEFLAGS という名前のレジスタを持っています(“E”は“Extended”から由来するもので,80286以前の16ビット幅のFLAGレジスタに対して32ビット拡張されていることを意味します)。

なお,実行される命令によっては,更新されるフラグが限定される,つまりそれ以外のフラグには影響を及ぼさない,といった挙動もありますので注意が必要です。

 Intel 80x86アーキテクチャでは,ここで紹介するフラグ以外にもPF(Parity Flag)およびAF(Adjust Flag)が提供されていますが,あまり一般的ではないのでここでの説明は割愛します。

「ゼロ」フラグ

実行結果がゼロか否かを保持するフラグビットを一般にゼロフラグ(Zero Flag)と呼びます。Intel 80x86アーキテクチャでは略称のZFで呼びます。

リスト1 ゼロフラグの挙動

    .text
    .align  4

    .global entry_point
entry_point:
    int3        # プログラム実行の一時停止

    movl    $2, %eax

    # 初期値の 2 から 1 を引くので,eax の値は 1
    subl    $1, %eax

    # eax の現在値 1 から 1 を引くので,eax の値は 0
    subl    $1, %eax

    .global end_of_program
end_of_program:
    int3        # プログラム実行の一時停止
    nop

実際にプログラムを動かしてみましょう。

図1 ゼロフラグの挙動確認

(gdb) disassemble entry_point
Dump of assembler code for function entry_point:
0x00401000 <entry_point+0>:    int3   
0x00401001 <entry_point+1>:    mov    $0x2,%eax
0x00401006 <entry_point+6>:    sub    $0x1,%eax
0x00401009 <entry_point+9>:    sub    $0x1,%eax
End of assembler dump.
(gdb) run
....
0x00401001 in entry_point ()
(gdb) stepi
0x00401006 in entry_point ()
    ※ "mov $0x02, %eax" の実行
(gdb) info register eax eflags
eax            0x2    2
eflags         0x246    [ PF ZF IF ]
(gdb) stepi
0x00401009 in entry_point ()
    ※ 1つ目の "sub $0x01, %eax" の実行
(gdb) info register eax eflags
eax            0x1    1
eflags         0x202    [ IF ] ※ ZF のクリア
(gdb) stepi
0x0040100c in end_of_program ()
    ※ 2 つ目の "sub $0x01, %eax" の実行
(gdb) info register eax eflags
eax            0x0    0
eflags         0x246    [ PF ZF IF ] ※ ZF のセット
(gdb) 

「キャリー」フラグ

符号無し演算における値域超えの有無を保持するフラグビットを一般にキャリーフラグ(Carry Flag)と呼びます。Intel 80x86アーキテクチャでは略称のCFで呼びます。

リスト2 キャリーフラグの挙動

    .text
    .align  4

    .global entry_point
entry_point:
    int3        # プログラム実行の一時停止

    # 符号無し 32 ビットの上限値
    movl    $0xffffffff, %eax

    # 符号無し 32 ビットの上限を超えた加算
    addl    $1, %eax

    # 0 ~ 31 ビットの範囲の演算
    addl    $1, %eax

    # 符号無し 32 ビットの下限(0)を下回る減算
    subl    $2, %eax

    .global end_of_program
end_of_program:
    int3        # プログラム実行の一時停止
    nop

実際にプログラムを動かしてみましょう。

図2 キャリーフラグの挙動確認

(gdb) disassemble entry_point
Dump of assembler code for function entry_point:
0x00401000 <entry_point+0>:    int3   
0x00401001 <entry_point+1>:    mov    $0xffffffff,%eax
0x00401006 <entry_point+6>:    add    $0x1,%eax
0x00401009 <entry_point+9>:    add    $0x1,%eax
0x0040100c <entry_point+12>:   sub    $0x2,%eax
End of assembler dump.
(gdb) run
....
0x00401001 in entry_point ()
(gdb) stepi
0x00401006 in entry_point ()
    ※ "mov $0xffffffff, %eax" の実行
(gdb) info register eax eflags
eax            0xffffffff    -1
eflags         0x246    [ PF ZF IF ]
(gdb) stepi
0x00401009 in entry_point ()
    ※ 1 つ目の "add $0x01, %eax" の実行
(gdb) info register eax eflags
eax            0x0    0
eflags         0x257    [ CF PF AF ZF IF ] ※ CF のセット
(gdb) stepi
0x0040100c in entry_point ()
    ※ 2 つ目の "add $0x01, %eax" の実行
(gdb) info register eax eflags
eax            0x1    1
eflags         0x202    [ IF ] ※ CF のクリア
(gdb) stepi
0x0040100f in end_of_program ()
    ※ "sub $0x01, %eax" の実行
(gdb) info register eax eflags
eax            0xffffffff    -1
eflags         0x297    [ CF PF AF SF IF ] ※ CF のセット
(gdb) 

上記の実行例ではCFとは別に,演算結果に応じてZFも変化しています。

著者プロフィール

藤原克則(ふじわらかつのり)

Mercurial三昧の日々が嵩じて, いつの間にやら『入門Mercurial Linux/Windows対応』を上梓。凝り性なのが災いして,年がら年中アップアップな一介の実装屋。最近は仕事の縁が元で,OpenSolarisに入れ込む毎日。

コメント

コメントの記入

パスサポ

多数の情報処理技術者試験対策書籍の発行実績を誇る技術評論社がお届けする,資格試験合格サイト「めざせ! 情報処理試験 パスサポ」が開設されました。

ピックアップ

サクセスストーリーに続く,快適サーバー運用管理のヒント!

データの増大,煩雑な管理,システムダウン,セキュリティなど,迫りくる課題からシステム管理者の負担を軽くするポイントを解説します。

gihyo.jp インフラエンジニア情報局

ネットワークやITにかかわるあらゆる業種で必要とされるインフラエンジニアに向けた技術情報や心構え,その魅力について多角的に紹介。

テストエンジニア ステーション

いま,ITに関わるあらゆる開発業務で注目されつつあるテスト系エンジニアをターゲットにしたコンテンツサイトを展開します。

一行クイックアンケート

gihyo.jpで取り上げてほしいネタは?

※検索はページ右上の検索ボックスをご利用ください。

その他の連載

読むウェブ ~本とインタラクション

ディスプレイで読む活字とそのインタラクション(interaction:相互作用)について,最新Webを紹介しながら読み解いていく。

いま,見ておきたいウェブサイト

この連載では,国内外の最新のウェブサイトを隔週更新で取り上げ,これら最新サイトの特徴や素晴らしい部分を,さまざまな角度から解説していきます。

Windows phoneアプリケーション開発入門

Windows Marcketplace for Mobileがサービス開始され,作成したアプリケーションを個人でも世界をターゲットに公開できる環境が整ってきました。これを機にWindows phoneアプリケーションの開発をしてみませんか?

ここは知っておくべき!Windows Server 2008技術TIPS

5年ぶりのサーバOSとなったWindows Server 2008が出荷されて早2年。2009年にはR2が出荷され,再び注目を集めています。発売前から実施したトレーニングによって感じた,インフラエンジニアの方々に知っておいていただきたい機能を中心にご紹介します。

キーパーソンが見るWeb業界

本連載はWeb Site Expert/gihyo.jpとの連動企画です。阿部淳也, 長谷川敦士, 森田雄のお三方による,Web業界をテーマにした座談会です。

きたみりゅうじの聞かせて珍プレー

ソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。みなさんからの投稿もお待ちしてます!

ActionScript 3.0で始めるオブジェクト指向スクリプティング

野中文雄氏が,簡単なスクリプトは書いたことがあるという初級者を対象に,ActionScript 3.0の基本からクラス定義までを解説します。

まだ間に合う「ITパスポート」受験対策 原山先生の短期合格塾

この連載では,4月18日のITパスポート試験の受験に向けて,短い期間で効率良く受験対策を行う方法や,確実に得点するための裏ワザなどを伝授していきます。

連載一覧

gihyo.jp

  • DEVELOPER STAGE
  • ADMINISTRATOR STAGE
  • WEB+DESIGN STAGE
  • LIFESTYLE STAGE
  • SCIENCE STAGE
  • NEWS & REPORT

書籍案内

  • 新刊書籍
  • 書籍ジャンル一覧
  • 書籍シリーズ一覧
  • 新刊ピックアップ
  • ロングセラー
  • 電脳会議

定期刊行物一覧

  • Software Design
  • WEB+DB PRESS
  • Web Site Expert
  • 組込みプレス