m4 はUNIXの標準コマンドの1つであり、古い歴史を持つマクロプロセッサである。しかし、やや使い方が難しく、しかも古典度が高く専門的なために、どうしても紹介のプライオリティが下がる傾向があって、日本語でマトモに書かれた解説にお目にかかったことがない。そこで、m4 に多少の経験値がある筆者があえて m4 のチュートリアルを書いて見せる。基本的な情報は m4 の info から仕入れており、それにいろいろな実例を加えて書いている。 マクロプロセッサ m4 とは? m4 の使い方 m4 のディレクティブ マクロ定義に関するディレクティブ マクロ置換の原則 マクロ引数 undefine と include 条件分岐 ループ メタ文字の入れ換え 組み込み文字列処理関数 その他 マクロプロセッサ m4 とは? m4 はマクロプロセッサである。つまり、Cプリプロセッサ cpp (今時だと gcc -E
先日Python 3.1a1 がリリースされました。 Python 3.0 は Python 2.6 に比べてパフォーマンスが悪かったのですが、Python3.1はPython2.6よりも速くなるかもしれません。 Python3.1のパフォーマンス向上は、主に次の2点が影響しています。 ioモジュールがC言語で書き直された computed goto の採用 (--with-computed-gotos というconfigureオプションで有効) computed goto という名前を聞き慣れなかったのですが、調べてみると Ruby 1.9 の VM (YARV) や、 Perl6 の VM として開発されとうとうリリースされた Parrot にも採用されている手法でした。今回は簡単に computed goto の紹介をしてみます。 とりあえず label as value C言語の規
Gaucheのソースではgotoって使われているんだろうかと思ってのぞいてみたら、vm.cにおもしろそうな箇所発見。 /* We take advantage of GCC's `computed goto' feature (see gcc.info, "Labels as Values"). */ #ifdef __GNUC__ #define SWITCH(val) goto *dispatch_table[val]; #define CASE(insn) SCM_CPP_CAT(LABEL_, insn) : #define DEFAULT LABEL_DEFAULT : #define DISPATCH /*empty*/ #define NEXT \ do { \ if (vm->queueNotEmpty) goto process_queue; \ FETCH_INSN(c
前回までに、デバッガを使用する上での最低限のことを覚えました。 ステップ実行 変数の表示、変更 ブレークポイント 今回は少しレベルを上げて、よりデバッガを使いこなすためのコマンドを紹介します。 ウォッチポイント ウォッチポイントはブレークポイントに近いものですが、ブレークポイントのように「ある地点に遭遇したら停止」ではなく、「監視している変数を操作したら停止」という流れになります。 ファイル内から該当する変数名を探せばいいと考えるかもしれませんが、C言語ではポインタによる変数の別名を付けることが可能であるため、そう単純にはいきません。 書き込みの監視 あまりよいサンプルが思いつかなかったため、簡単で無意味な例を示します。 counter.c #include <stdio.h> void set_counter(int *); int count = 1; int watchee = 0;
何回やっても忘れてしまうシリーズ。 カスタムなリンカスクリプトを使ってビルドするときに、オリジナルのリンカスクリプトを参照したいことはよくある いあ、カスタムなリンカスクリプトを使うこと自体が滅多にないという意見はあるが(^^; そんな時は以下のコマンドを用いる ld --verbose 以下は出力例 GNU ld version 2.15.92.0.2 20040927 Supported emulations: elf64_ia64 elf_i386 i386linux using internal linker script: ================================================== /* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("e
試行錯誤してインラインアセンブラのチュートリアルが完成した。 やったぞ,なんだか分からないけど俺はやったんだ! GAS構文の概要 まず,GAS のシンタックスについて見ていく。GAS は標準で AT&T 記法を使用しているが,.intel_syntax ディレクティブにより intel 記法を使うこともできる。忌々しい AT&T 記法とはおさらばだ! intel 記法を使うには,アセンブラファイルの先頭に次の行を置く。 .intel_syntax noprefix また,C ファイルから作成される GAS を intel 記法で出力させる(又は,インラインアセンブラで intel 記法を使う場合)には GCC にこんなオプションを加えてやる: gcc -masm=intel ... intel 記法が手に入りテンションが上がってきたところで,さっそく構文の説明を始めることにしよう。一応注意
gccでインラインアセンブリ機能を利用しようとしたら、だいぶ記法が変態的(って言ったら怒られるかな^ー^;)だったのでメモ。 1 #include <stdio.h> 2 3 int main(int argc,char* argv[]){ 4 int a=10,b=0; 5 6 printf("before:%d\n",b); 7 8 //----memo---- 9 //通常のGASの構文では、レジスタを利用するためにプレフィックスとして 10 //%を1つだけつける。 11 //ところが、gccのインラインアセンブリの構文では、 12 //C言語中で宣言された変数を利用するために、レジスタを利用する 13 //プレフィックスを変更してあげる必要がある。具体的には、 14 // レジスタ:%%レジスタ名 15 // 変数名 :%C言語中の変数名 16 //となる。 17 // 18 /
Linux/インラインアセンブラ Linux get_current 関数を例にインラインアセンブラを説明する. Linux カーネルで使われているアセンブラは GAS (GNU Assembler) であり,インラインアセンブラの表記もこれに従う.GAS は Intel 表記ではなく,AT&T 表記を利用するアセンブラであり,Intel のマニュアルを読みながら GAS でコーディングする場合は注意が必要である. get_current (include/asm/current.h)の定義は次のようになっている. static inline struct task_struct * get_current(void) { struct task_struct *current; __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL
gccのasm命令を使うことで,Cの中でインラインアセンブラを使える. 【構文】 asm volatile ("アセンブラテンプレート" : "出力オペランド" : "入力オペランド" : "アセンブラの実行で変更されてしまうもの"); [アセンブラテンプレート] ニーモニックを指定する. "cpuid"とか"mov"とか. 複数指定することもできる. [出力オペランド] 下記のように指定する "=a" (出力先変数), "=b" (出力先変数) ex) "=a (buf)" はeaxレジスタの内容を変数bufに出力することを示す. [入力オペランド] "a" (入力)のように指定する "0"(入力)と指定すると,1番目に指定した出力オペランドの制約条件を流用する. ex) "a" (0) はEAXレジスタに入力として0を与えることを示す. 【オペランドの制約条件】 "=" asmが終わっ
gccのコマンドラインオプションを調べる時にはいままではWEB上のマニュアルを見ていました。 http://gcc.gnu.org/onlinedocs/ 特に、ちょっとオプションのスペルを確認したい時などはコマンドラインオプションのサマリーのページでブラウザのページ内検索の機能で探していました。 でもここに書いてないオプションもあったりします。 例えば、ソースコードのcharsetを指定するオプションを探したのですがマニュアルに見当たりません。そのためにgcc本体のソースコードを検索したりしたのですが、もっと簡単な方法を見つけました。 $gcc -v --help これでgccとgccから呼びだされるcc1, cc1plus, as, ldなどのコマンドラインオプションの簡単な説明が出力されます。 大量にでる(1000行以上)ので一度ファイルに落してエディタなどでみるといいでしょう。 $
nchaOSではfirstbootからsecondboot、さらにstartKernelへの移動をljmp命令などで行い、それぞれのバイナリをcatなどでつなげてメモリ上の位置を制御していたが、今回はldのリンカスクリプト等を使い制御していきたいと思う。 そこでリンカスクリプトやその周辺についてメモを適当にまとめてみる。 オブジェクトファイル 1. asの「-a」オプションによりアセンブリリストを出力する 2. objdump -h objfile(objfileはas後のファイル)によりSECTIONのヘッダー情報を出力 3. objdump -t objfile によりシンボル情報を出力 リンカスクリプト 主な機能 1. ファイルの指定方法 ld -T file objfile.o -o outfile 2. 出力ファイルのメモリレイアウト方法 SECTIONS { . = 0x900
○GCC x86インラインアセンブラ asm ("命令 source,dest"); ■グローバル変数 --------------------------------------------------------- そのまま使えます #include <stdio.h> int i; int j; main(){ i=10; asm ("movl i,%eax"); asm ("add $10,%eax"); //数値は先頭に$マークを付ける asm ("movl %eax,j"); printf("%d %d\n",i,j); } ▼上のプログラムの書き方を変えたもの #include <stdio.h> int i; int j; main(){ i=10; asm ( "movl i,%eax \n\t" "add $10,%eax \n\t" "movl %eax,j"
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く