熱血! アセンブラ入門

概 要

コンピュータとプログラミングを愛するすべての人に捧げるアセンブラ入門。700ページ以上にわたり、40種類のアセンブラを読み説きながら、アセンブラが現役であり続ける理由を考察します。アセンブラを読みはじめるのに、CPUの仕様書や、英語力なんて必要ないのです。研究者がこだわる「わかる喜び」、エンジニアがこだわる「動く喜び」を追い求める「熱意」こそが大切です。本書を片手にオンリーワン・エンジニアを目指しましょう。

著者 坂井弘亮
価格 本体4000円(税別)
ISBN 978-4-7980-4180-3
発売日 2014/9/27
判型 B5変
色数 1色
ページ数 800
CD/DVD
ダウンロード
表紙イメージ
購入 アマゾンで購入する
楽天で購入する

※リンク先によっては、販売ページが用意されていないことがあります。あらかじめご了承ください。

新しいウィンドウで開く 書籍購入のご案内

サポート

サポート情報は以下からご参照下さい。

サポート情報へのリンク

目次

第1部 基礎編:まずはアセンブラに慣れよう

01 まずは基本操作を覚えて,アセンブラに慣れよう!

01.01 アセンブラを見てみよう

01.01.01 3つの関数だけを見てみる

01.01.02 まずは,目的を意識して読んでみよう

01.01.03 アセンブラの読み方を知ろう

01.01.04 「機械語」と「ニーモニック」

01.01.05 固定長の命令

01.01.06 リターン命令

01.01.07 「アセンブラ」と「アセンブリ言語」

01.01.08 レジスタの使われかたを推測しよう

01.02 バイナリエディタで確認しよう

01.02.01 バイナリエディタで見てみる

01.02.02 機械語コードの書き換え

01.02.03 再度,逆アセンブルする

01.03 まとめ

02 PowerPCの数値の扱いかたを見てみよう

02.01 まずは,サイズを見てみよう - PowerPCのビット数を知る -

02.01.01 int型のサイズ

02.01.02 ポインタ型のサイズ

02.01.03 short型とlong型のサイズ

02.02 値の代入を見てみよう - PowerPCの代入の方法 -

02.02.01 2バイト値の代入

02.02.02 ひとつの疑問

02.02.03 4バイト値の代入

02.02.04 2回に分けて代入する

02.03 引数の渡しかた

02.03.01 第1引数と第2引数を渡す

02.03.02 第1引数と戻り値のレジスタは同じ

02.04 まとめ

03 MIPSのアセンブラを見てみよう

03.01 MIPSって何?

03.02 アセンブラを見てみる

03.02.01 アセンブラのファイル

03.02.02 MIPSのアセンブラ

03.03 関数からの返りかた

03.03.01 ジャンプ命令

03.03.02 命令の順序がひっくり返っている?

03.03.03 MIPSは遅延スロットを持つ

03.03.04 ゼロの代入が特別扱いになっている?

03.03.05 MIPSはゼロレジスタを持つ

03.04 数値の扱いかた

03.04.01 MIPSは32ビットCPU

03.04.02 大きな値は2回に分けて代入する

03.04.03 引数の渡しかた

03.04.04 MIPSは第1引数と戻り値のレジスタが異なる

03.05 レジスタ番号

03.05.01 レジスタ番号を見てみる

03.05.02 特殊レジスタの扱い

03.06 まとめ

04 演算処理を見てみよう

04.01 レジスタ間の演算

04.01.01 add命令のオペランド

04.01.02 オペランドの順番を推測する

04.02 オペランドの指定方法

04.02.01 add命令を並べて比較してみる

04.02.02 オペランドのフォーマットを推測する

04.02.03 第2,第3オペランドのフォーマット

04.03 バイナリエディタで確認してみる

04.03.01 書き換え位置の計算方法

04.03.02 アドレスの計算方法

04.04 レジスタと即値の演算

04.04.01 レジスタと即値の演算

04.04.02 後半2バイトが即値のフィールドになっている

04.04.03 or命令による論理演算

04.04.04 MIPSではどうなっているのか?

04.05 まとめ

05 その他のCPUを見てみる ?RISC編

05.01 SHを見てみよう

05.01.01 SHの機械語コードは2バイト長

05.01.02 2バイト命令で,どうやって即値を扱うのか?

05.01.03 絶対アドレスと相対アドレス

05.01.04 SHはPC相対のアドレッシングモードを持つ

05.01.05 SHのPC相対はややこしい

05.01.06 4バイトの定数値は?

05.01.07 オフセット値の範囲外のアドレスはどうなるのか?

05.01.08 1命令で代入できる場合もある

05.01.09 引数の扱いはどうなっているのか

05.01.10 2オペランド方式と3オペランド方式

05.02 ARMを見てみよう

05.02.01 ARMは条件コードを持っている

05.02.02 ARMはリトルエンディアン

05.02.03 ARMのリターン命令

05.02.04 多バイト値の扱いに特徴がある

05.02.05 ARMはプログラムカウンタが2つ先の命令を指す

05.02.06 ゼロ付近の値は1命令で生成できる

05.02.07 複雑な値は複数命令で生成する

05.02.08 引数の渡しかたはPowerPCと似ている

05.02.09 加算処理は3オペランド方式で行なわれる

05.03 まとめ

06 命令のエイリアス

06.01 PowerPCのli命令の場合

06.01.01 li命令の機械語コードを見てみる

06.01.02 li命令とaddi命令はオペコードが同じになっている

06.01.03 li命令はゼロ指定のaddi命令になっている

06.01.04 アセンブラのエイリアス

06.02 PowerPCのmr命令の場合

06.02.01 mr命令の機械語コード

06.02.02 mr命令はor命令のエイリアスになっている

06.03 MIPSのli命令の場合

06.03.01 MIPSも「li」という命令を持っている

06.03.02 レジスタ番号を出力させてみる

06.03.03 レジスタを指定している部分を探す

06.03.04 li命令はaddiu命令のエイリアスになっている

06.04 MIPSのmove命令の場合

06.04.01 move命令はaddu命令のエイリアス

06.04.02 並べて比較してみる

06.04.03 2箇所のどちらなのかを調べる

06.04.04 ゼロレジスタが指定されている?

06.05 nop命令もエイリアスになっている

06.05.01 nop命令もエイリアスになっている

06.05.02 sll命令とは何か?

06.05.03 sll命令はシフト演算を行う命令

06.05.04 PowerPCではnopはori命令になっている

06.06 まとめ

07 メモリ操作

07.01 PowerPCのメモリ操作

07.01.01 ロードとストア

07.01.02 構造体のメンバのアクセス

07.01.03 アドレッシングモード

07.01.04 静的変数のアドレスの格納

07.01.05 静的変数へのアクセス

07.02 MIPSでのメモリ操作

07.02.01 ロード/ストアはPowerPCと似ている

07.02.02 グローバルポインタ

07.03 ARMでのメモリ操作

07.03.01 ARMでもディスプレースメント付きレジスタ間接が利用できる

07.03.02 PC相対によりアドレスを設定する

07.04 まとめ

08 その他のCPUを見てみる ?CISC編

08.01 RISCとCISC

08.01.01 RISCは高速化のためのアーキテクチャ

08.01.02 CISCはメモリが低速だった時代のアーキテクチャ

08.01.03 CISCはアセンブラプログラマのためのアーキテクチャ

08.01.04 RISCはパイプラインを意識したアーキテクチャ

08.01.05 RISCとCISCの区別

08.01.06 命令セットでRISCとCISCを区別する

08.01.07 CISCライクな命令セットは,組込み分野に向いている

08.01.08 「RISC」「CISC」と,もうひとつの分類「マイコン」

08.02 H8

08.02.01 H8は可変長命令

08.02.02 H8は16ビットCPU

08.02.03 H8は16ビットCPUなのに,32ビット値をどうやって扱うのか

08.02.04 引数の渡しかた

08.02.05 加算命令は2オペランドになっている

08.02.06 レジスタの個数は?

08.02.07 H8は省メモリサイズを意識したアーキテクチャ

08.02.08 メモリ操作を見てみる

08.02.09 H8では,値の移動はすべてmov命令で行う

08.02.10 ディスプレースメント付きレジスタ間接も使える

08.02.11 アドレスは16ビットになっている

08.03 i386

08.03.01 i386は,もっと極端な可変長命令になっている

08.03.02 多バイト値をそのまま扱うことができる

08.03.03 引数はスタック経由で渡される

08.03.04 メモリ上の値を直接加算することができる

08.03.05 インクリメントするだけの専用命令がある

08.03.06 6バイトや7バイトの命令もある

08.03.07 直接アドレスによるメモリアクセスも行なえる

08.04 まとめ

09 スタックの使いかた

09.01 スタックとは何か?

09.02 MIPSのスタック操作

09.02.01 volatileで最適化を抑止してコンパイルする

09.02.02 関数の先頭ではスタックポインタの操作が行われている

09.02.03 スタックフレーム

09.02.04 スタック上の値を利用する

09.02.05 最適化をしないとどうなるか?

09.02.06 関数の処理内容はブロック単位に分けることができる

09.02.07 MIPSのスタックポインタの実体は何か?

09.02.08 ABIはバイナリの規約

09.03 PowerPCのスタック操作

09.03.01 PowerPCではr1レジスタがスタックポインタになっている

09.03.02 PowerPCのスタックフレームは解析しやすい構造になっている

09.03.03 スタック操作はアトミックに行う必要がある

09.04 ARM,SH,H8,i386のスタック操作も見てみよう

09.04.01 ARMはMIPSやPowerPCと似ているようだ

09.04.02 SHも似ているようだ

09.04.03 H8もだいたい同じなようだ

09.04.04 i386は1命令で自動変数を用意している

09.04.05 スタックの一般的な共通事項

09.05 まとめ

10 関数呼び出し

10.01 MIPSの関数呼び出し

10.01.01 MIPSの関数呼び出しはjal命令で行われる

10.01.02 関数呼び出し時に,レジスタをスタックに保存している

10.01.03 raレジスタには戻り先のアドレスが格納されている

10.01.04 raレジスタはハードウェア的に特別なものになっている

10.02 PowerPCの関数呼び出し

10.02.01 PowerPCとMIPSの関数呼び出し手順は似ている

10.02.02 PowerPCはリンクレジスタを持っている

10.02.03 特殊レジスタに対するMIPSとPowerPCの考え方の違い

10.02.04 PowerPCのリンクレジスタの保存先は,ひとつ前のスタックフレームになっている

10.02.05 RISC系CPUはレジスタベースで動作している

10.03 ARMの関数呼び出し

10.03.01 ARMは複数レジスタをスタックに保存する命令がある

10.03.02 ARMは特殊レジスタを汎用レジスタとして持っている

10.03.03 ARMのスタック構造を考える

10.03.04 ポインタ経由での関数呼び出し

10.03.05 ARMの命令セットは,あまりRISCっぽくないように思える

10.03.06 フレームポインタとは何か?

10.03.07 フレームポインタを有効化してみる

10.04 SHの関数呼び出し

10.04.01 SHは「プリデクリメントレジスタ間接」というアドレッシングモードを持つ

10.04.02 SHではポインタ経由で関数呼び出しが行われる

10.04.03 関数呼び出しのアドレス指定方法

10.04.04 SHは多ビットのオペランドを取れない

10.05 CISC系CPUの関数呼び出し

10.05.01 H8では,戻り先アドレスはスタックに保存される

10.05.02 i386では引数もスタック経由で渡される

10.06 まとめ

11 条件分岐

11.01 「ジャンプ」と「分岐」

11.02 H8の条件分岐

11.02.01 「cmp」が比較命令のようだ

11.02.02 分岐命令は頭に「b」がつく

11.02.03 比較結果の保存先

11.02.04 ループ処理はどうなっているのか?

11.02.05 ループの継続の判断も,条件分岐によって行なわれている

11.02.06 ループの先頭でも条件分岐を行なっている

11.03 PowerPCの条件分岐

11.03.01 「cmpw」という比較命令があるようだ

11.03.02 比較結果はCRレジスタに格納される

11.04 i386の条件分岐

11.04.01 i386は「ブランチ」でなく「ジャンプ」と呼ぶようだ

11.04.02 「分岐(ブランチ)」と「ジャンプ」

11.05 SHの条件分岐

11.05.01 SHでは,比較命令のほうで分岐条件を指定する

11.05.02 条件分岐では真か偽かのみを見て判断している

11.05.03 なぜフラグを1本にしぼっているのか

11.06 MIPSの条件分岐

11.06.01 比較と分岐を1命令で行っている

11.07 ARMの条件分岐

11.07.01 そもそも条件分岐を行っていない

11.07.02 では,条件分岐したい場合にはどうするのか?

11.08 まとめ

12 複雑な処理を読んでみよう

12.01 MIPSの場合

12.01.01 関数をブロック分けして読みとく

12.01.02 関数の先頭と末尾に着目する

12.01.03 関数のプロローグとエピローグ

12.01.04 関数の処理の本体

12.01.05 ブロック化してみる

12.01.06 もう少し複雑な処理も見てみよう

12.01.07 保存されるレジスタと,保存されないレジスタ

12.01.08 なぜs0レジスタが利用されるのか?

12.02 PowerPCの場合

12.02.01 やはりMIPSとだいたい似ているようだ

12.02.02 関数内部で行なわれる処理

12.03 ARMとSHの場合

12.03.01 ARMもほとんど同じようだ

12.03.02 そしてSHも,ほとんど同じようだ

12.04 H8とi386の場合

12.04.01 H8やi386では,戻り先アドレスを退避する必要が無い

12.04.02 不揮発性レジスタの扱いはMIPSなどと同じようだ

12.05 まとめ

第2部 応用編:さまざまなCPUのアセンブラを見てみよう

13 他のRISC系CPUを見てみよう

13.01 SPARC

13.01.01 SPARCはコテコテのRISCプロセッサのようだ

13.01.02 レジスタ・ウィンドウとは何か?

13.01.03 SPARCのレジスタ・ウィンドウの仕組み

13.01.04 レジスタ・ウィンドウと関数呼び出し

13.01.05 restore命令でのレジスタ指定

13.01.06 リーフ関数ではレジスタ・ウィンドウの操作は不要になる

13.01.07 32ビット値の複数回での代入は,異なるビット数で行われる

13.01.08 レジスタ指定のフィールドが分散しているようだ

13.01.09 まとめ

13.02 PA-RISC

13.02.01 遅延スロットの有無を切替えられる

13.02.02 符号ビットが最下位にある

13.02.03 即値が16ビットずつになっていない

13.02.04 引数を渡すレジスタが逆順になっている

13.02.05 静的変数へのアクセスには,グローバルポインタが利用される

13.02.06 スタックは上方伸長のようだ

13.02.07 RISCでディスプレースメント付きレジスタ間接が多い理由

13.02.08 まとめ

14 64ビット・プロセッサも見てみよう

14.01 Alpha

14.01.01 Alphaは64ビット・アーキテクチャ

14.01.02 リトルエンディアンになっているようだ

14.01.03 ひとつ大きな値が格納されている?

14.01.04 シフトされた値が代入されている

14.01.05 レジスタ名がMIPSと似ているようだ

14.01.06 レジスタ番号を推測してみる

14.01.07 まとめ

14.02 その他の64ビット・プロセッサ

14.02.01 PowerPC(64ビット)

14.02.02 MIPS(64ビット)

14.02.03 SH(64ビット)

14.02.04 x86-64

14.02.05 IA-64

14.02.06 MMIX

14.02.07 まとめ

15 組込み向け32ビットCPUのアセンブラを見てみよう

15.01 M32R

15.01.01 2命令が1セットで扱われている?

15.01.02 4バイト命令も使われているようだ

15.01.03 ゼロ付近の値は効率的に代入することができる

15.01.04 演算は2オペランド形式になっている

15.01.05 メモリ操作はRISCっぽい感じのようだ

15.01.06 24ビットアドレスは1命令で扱える

15.01.07 関数の先頭は4バイトアラインメントされている必要がある?

15.01.08 まとめ

15.02 V850

15.02.01 即値が機械語コードの先頭にある?

15.02.02 4バイト値は符号拡張を考慮して代入する

15.02.03 レジスタの扱いかたを見てみる

15.02.04 ディスプレースメント付きレジスタ間接でのアクセスもできる

15.02.05 ディスプレースメントは2の倍数になる

15.02.06 関数呼び出しのために関数が呼び出される?

15.02.07 nop命令がオールゼロになっている

15.02.08 まとめ

15.03 i960

15.03.01 関数の先頭が16バイトアラインメントされている

15.03.02 ごくごくフツーのRISCプロセッサみたい

15.03.03 スタックが上方伸長のようだ

15.03.04 レジスタウィンドウを持っているのか?

15.03.05 まとめ

15.04 MN10300

15.04.01 1バイト命令を持っている

15.04.02 3バイト命令や6バイト命令もあるようだ

15.04.03 第3引数はスタックで渡される

15.04.04 アドレスを扱うレジスタが別にある

15.04.05 代入はすべてmov命令で行なう

15.04.06 まとめ

15.05 FR30

15.05.01 遅延スロットを持つリターンと持たないリターンがある

15.05.02 加算命令は2オペランド形式のようだ

15.05.03 ディスプレースメント付きレジスタ間接が使えないようだ

15.05.04 ディスプレースメントが使えないため,スタック操作が面倒になっている

15.05.05 まとめ

15.06 FR-V

15.06.01 VLIWのため,命令数がそろっている

15.06.02 ゼロレジスタを持っているようだ

15.06.03 グローバルポインタも持っているようだ

15.06.04 まとめ

15.07 Xtensa

15.07.01 .literalというセクションがあるようだ

15.07.02 命令長は2バイトか3バイト固定長?

15.07.03 多バイト定数は.literalからロードする

15.07.04 引数の渡しかたは普通のようだ

15.07.05 メモリアクセスやスタックの使いかたも普通のRISCみたいだ

15.07.06 レジスタウィンドウを持っている?

15.07.07 まとめ

16 マイコンのアセンブラを見てみよう

16.01 AVR

16.01.01 8ビットマイコンだが,int型は16ビットで扱われる

16.01.02 命令によっては使えないレジスタがある

16.01.03 引数もレジスタ2個のペアで渡されている

16.01.04 加算はキャリフラグを利用して行われている

16.01.05 インデックスレジスタを持っている

16.01.06 スタックの使いかたには,だいぶ癖があるようだ

16.01.07 I/O命令が使われている

16.01.08 スタックはエンプティ・スタックになっている

16.01.09 まとめ

16.02 Xstormy16

16.02.01 アドレス幅は16ビットのようだ

16.02.02 4バイト値はレジスタ2個で扱う

16.02.03 引数の扱いは普通の感じのようだ

16.02.04 メモリアクセスも見てみよう

16.02.05 スタックが上方伸長のようだ

16.02.06 まとめ

17 昔ながらのマイコンのアセンブラも見てみよう

17.01 68HC11

17.01.01 8ビットマイコンでは,1バイトでも節約したい

17.01.02 でもint型は32ビットのようだ

17.01.03 引数はスタックで渡しているようだ

17.01.04 アキュームレータ方式になっている

17.01.05 レジスタ交換命令を持っているようだ

17.01.06 加算は桁上がりにキャリを使っている

17.01.07 単なる加算でも,条件分岐が使われることがある

17.01.08 アドレスを直接指定することもできるようだ

17.01.09 スタックの獲得は,スタック退避命令を繰り返すことで行なわれる

17.01.10 メモリをレジスタがわりに利用する方法がある

17.01.11 まとめ

17.02 68000

17.02.01 実質的に,32ビットのアセンブラになっている

17.02.02 4バイトの即値を直接扱える

17.02.03 引数はスタック経由で渡される

17.02.04 メモリ上の値を直接加算することができる

17.02.05 直接アドレスによるロードが行なえる

17.02.06 即値を2つ指定するような命令もある

17.02.07 まとめ

18 CISC系のCPUを見てみよう

18.01 VAX

18.01.01 「ミニコン」とは何か

18.01.02 ゼロクリア専用の命令を持っている

18.01.03 VAXはPDP-11を32ビット拡張したコンピュータ

18.01.04 可変長命令なので,4バイトの即値もそのまま扱える

18.01.05 引数はスタックで渡される

18.01.06 加算命令のオペランドにメモリを指定することができる

18.01.07 メモリ上の値を直接扱える

18.01.08 movl命令がさまざまな種類のオペランドをとっている

18.01.09 静的変数もやはりmovl命令で扱われている

18.01.10 もはや何でもできそうだ

18.01.11 まとめ

18.02 PDP-11

18.02.01 16ビット・ミニコン

18.02.02 4バイト値はレジスタ2個で扱う

18.02.03 アセンブラは8進数表記になっている

18.02.04 gccのバグだろうか

18.02.05 引数はスタック経由で渡される

18.02.06 「インクリメント演算子」の元になった命令がある

18.02.07 2段階のメモリアクセスも1命令でできる

18.02.08 PC相対を探ってみよう

18.02.09 PC相対で即値を表現する.これは美しい!

18.02.10 PDPエンディアンとは?

18.02.11 まとめ

19 メインフレームのアセンブラを見てみよう

19.01 S/390

19.01.01 リターン命令がわからない!

19.01.02 関数のお尻が埋められている?

19.01.03 プログラムカウンタを扱っているようだ

19.01.04 メモリアクセスはふつうの感じのようだ

19.01.05 スタックが大量に獲得されている?

19.01.06 直後の命令を関数コールすることで,プログラムカウンタの値を取得する

19.01.07 マルチプル・ロード/ストア命令によるスタック操作

19.01.08 まとめ

20 その他のアセンブラについても見てみよう

20.01 縮小命令セットを見てみよう

20.01.01 MIPS16

20.01.02 Thumb(ARMの16ビット命令)

20.01.03 縮小命令セットの呼び出しかた

20.01.04 縮小命令セットの効果と影響

20.02 ビット幅を変化させてみる

20.02.01 AVR(8ビットint)

20.02.02 68HC11(16ビットint)

20.02.03 H8/300H

20.02.04 まとめ

20.03 ARM系プロセッサ

20.03.01 StrongARM

20.03.02 XScale

20.03.03 まとめ

20.04 謎のCPUも見てみよう

20.04.01 ARC

20.04.02 CRIS

20.04.03 M・CORE

20.04.04 まとめ

20.05 大学生が作ったCPUを見てみよう

20.05.01 MIST32向けのクロスコンパイラの作成

20.05.02 16ビットの即値は,分割されて格納されている

20.05.03 演算は2オペランド形式のようだ

20.05.04 ディスプレースメント付きレジスタ間接を持っていない?

20.05.05 スタックフレームの外をアクセスしている?

20.05.06 関数呼び出しは,2命令で行なう

20.05.07 アウトオブオーダー実行のために

20.05.08 まとめ

第3部 番外編:アセンブラの出力環境を構築しよう

21 アセンブラ出力環境の構築方法

21.01 環境構築の準備

21.01.01 本書で利用するツール

21.01.02 やっていること

21.01.03 まずはホストコンパイラが必要

21.01.04 アーキテクチャ

21.01.05 ベース環境

21.01.06 必要スペック(HDD容量)

21.01.07 必要スペック(CPU速度)

21.01.08 PCをどうするか?

21.02 クロスコンパイル環境の構築

21.02.01 前準備

21.02.02 サポートサイトを確認してください

21.02.03 必要なファイルの準備

21.02.04 スクリプト類の展開

21.02.05 アーカイブの展開とパッチ当て

21.02.06 binutilsのビルド

21.02.07 gccのビルド

21.02.08 gdbのビルド

21.02.09 ビルドをまとめて実施するには

21.02.10 アセンブラを出力してみる

21.02.11 シミュレータで実行してみる

21.02.12 newlibを利用する

21.02.13 アンインストールするには

21.03 makeによる処理の詳細

21.03.01 「make」をすると何が起きるのか

21.03.02 「make」は何をしてくれるのか

21.03.03 「make」が便利なところ

21.04 さらにいろいろやってみるには

21.04.01 gccのバージョン4系を利用する

21.04.02 アセンブラの出力方法を変えてみる

21.04.03 新しいアーキテクチャに対応する

21.05 まとめ

22 「Hello World」を動かしてみる

22.01 シミュレータで「Hello World」を実行する

22.01.01 高機能デバッガ「gdb」

22.01.02 シミュレータで「Hello World」を動作させる

22.01.03 printf()を使わないためには何が必要か?

22.01.04 APIを利用せずにHello Worldを書いてみる

22.02 何をすればシミュレータで文字列出力できるのか?

22.02.01 システムコールをシミュレートする

22.02.02 特殊命令を実装する

22.02.03 周辺デバイスのシミュレートも行う

22.02.04 仮想的なデバイスを実装する

22.03 動作のために必要な対応は?

22.03.01 スタートアップも必要

22.03.02 プログラムの終了の方法

22.03.03 どうやって調べるか?

22.03.04 シミュレータ利用のサンプルコード

22.04 まとめ

23 シミュレータ対応の実際

23.01 H8のシミュレータ対応

23.01.01 シミュレータのソースコードを読む

23.01.02 write()の実行場所

23.01.03 引数は関数呼び出しと互換の方法で渡される

23.01.04 _exit()による終了

23.01.05 スタートアップの実装

23.01.06 実行してみる

23.02 SHのシミュレータ対応

23.02.01 SHも,シミュレータのソースコードはそれほど多くない

23.02.02 トラップ命令を利用するようだ

23.02.03 引数を渡すレジスタがひとつずれている

23.02.04 スタートアップを実装して実行してみる

23.03 ARMのシミュレータ対応

23.03.01 ソースコードはそれなりに多い

23.03.02 大規模なソースコードを読むときのコツは?

23.03.03 write()の処理部分

23.03.04 しかし,うまく実行できないようだ

23.03.05 gdbで動作を追ってみる

23.03.06 条件コードの考慮が必要になる

23.04 MIPSのシミュレータ対応

23.04.01 まずはファイル名で判別する

23.04.02 write()の処理箇所を探す

23.04.03 予約命令?

23.04.04 終了とスタートアップ

23.04.05 それでもうまく実行できない

23.04.06 アドレスが不正?

23.04.07 まだうまく動かない!

23.04.08 グローバルポインタの設定が必要

23.04.09 終了処理を見直す

23.05 PowerPCのシミュレータ対応

23.05.01 NetBSDやLinuxをシミュレートしているようだ

23.05.02 引数は関数呼び出しと同じ方法で渡される

23.05.03 エラー処理について考える

23.05.04 エラーの判断とerrnoの設定

23.06 i386

23.06.01 FreeBSDのシステムコール処理を見てみる

23.06.02 「int 0x80」がシステムコールの入口になっている

23.06.03 FreeBSDではスタック経由で引数が渡される

23.06.04 Linuxのシステムコール処理を見てみる

23.06.05 Linuxではレジスタ経由で引数が渡される

23.06.06 FreeBSDとLinuxの,システムコール引数の渡しかたの違い

23.06.07 バイABIな実行形式を作成する

23.06.08 実行してみる

23.07 残りのアーキテクチャを対応する

23.07.01 AVR

23.07.02 CRIS

23.07.03 FR-V

23.07.04 その他のアーキテクチャ

23.08 その他の対応

23.08.01 エラーの返しかた

23.08.02 printf()を使えるようにする

23.08.03 浮動小数演算について

23.09 まとめ

PR

秀和システム