• アセンブリ超入門

    2013-12-25 22:082

    Cって結局アセンブリだろうから、

    インラインで書いてあろうが、.cと.asm混合だろうが、
    読めるようになりたいよね? ね!?


    という訳で軽くアセンブリ入門したのでメモ。
    本当に初心者で、まだアセンブリわかんなくて興味ある程度の人向け。


    有名な2大?アセンブリ言語にGASとNASMってのがあるらしい。
    GASは拡張子.sでこれはgccでCをビルドする時に生成されているアセンブリそのまんまらしく、

    gcc -S hello.c

    でCで書いたコードのアセンブリバージョンが出力される。

    #include <stdio.h>

    void main(){
    printf("HELLO \n");
    }


    .file "hello.c"
    .def ___main; .scl 2; .type 32; .endef
    .section .rdata,"dr"
    LC0:
    .ascii "HELLO \12\0"
    .text
    .globl _main
    .def _main; .scl 2; .type 32; .endef
    _main:
    LFB7:
    .cfi_startproc....※続く


    しっ知ってたし。。(゚o゚;;、すっ、すごくなんかないし。。



    Windows用バイナリのビルド方法(gccインスコ済、win7homepresp1-64bit環境で確認)

    as -o hello.o hello.s
    gcc hello.o
    a
    ↑(実行)


    NASMは拡張し.asmで、インテル系に特化した感じな模様
    CPU最適化の処理が書きたかったら、
    mmx/sseとかはNASM、ARMはGASで、みたいな対応かな。
    global _main
    extern _printf

    section .text
    _main:
    push message
    call _printf
    add esp, 4
    ret
    message:
    db 'Hello, World', 10, 0

    Windows用バイナリのビルドは

    nasm -fwin32 helloworld.asm
    gcc helloworld.obj
    a
    ↑(実行)

    サンプルコードがあるサイトは多いけど、
    MS-DOSとか、古かったり、リンクをldコマンドでやったりしているのを試したけど、
    どうしてもうまくいかなかった。
    意外とメンドカッタ


    で、GASをCと混合でビルドするには、C側で関数をextern宣言しておく必要があったり、NASMはプロトタイプ宣言?的な記述が必要。

    あとeclipse+CDT環境でのビルドを考えないと、
    また追々やろう。




  • 広告
  • eclipse CDTでのライブラリの参照

    2013-11-29 00:59

    前回Cygwinで使ってるビルドセットを使って、
    eclipse上でコードを弄るやり方を紹介?したんだけど、

    makefileを自動生成に設定したCDTのプロジェクトで、ライブラリの参照方法がわかったのでメモ。

    これは新規ブロジェクト作成で実行可能なプロジェクトにするか、後からプロジェクトのプロパティの「C/C++ビルド」でも設定できる。


    例えば前回の例でffmpegはちょっと仰々しいけど、
    lame(mp3)のライブラリだけを使用して、エンコード/デコードのプログラムを書きたい場合、

    javarにはライブラリって言われても、やることはjarにパス通すくらいだけど、*.jarはそれ自体が実行可能だったりだけど。
    cygwinとかlinuxでは静的ライブラリが*.aで、動的ライブラリは*.so、
    windowsでは静的ライブラリが*.lib、動的ライブラリが*.dllみたいな感じで、
    リンクして、モジュールの処理が他のプログラムから呼べる。
    リンクってなんなんだかよーわからん。。またいつか考えるとして


    ライブラリの作成は、linuxだったら先の方法でlameをビルドすると、/usr/local/libにlibmp3lame.aがあるのでそれを使えばいいけど、Windows用のバイナリの作成方法が何度やってもうまくいかなかったので、ググるとバイナリでlibmp3lame-static.libとlame_enc.dllを見つけたからそれを使ってみた。*.aを参照してもWindowsのランタイムとは関係なから?いける模様。


    ・CDTでの参照方法
    ライブラリを使用するプロジェクトのプロパティで「C/C++」→「パスおよびシンボル」で、
    「ライブラリー・パス」タブで*.libか*.dllのあるディレクトリを設定、
    「ライブラリー」タブでライブラリーの最初のlibと最後の.libを抜いた名前
    例)
    libmp3lame.a→mp3lame
    lame_enc.dll→lame_enc

    を設定してプロジェクトをビルドする。

    (これはDebug又はRelease配下にあるobjects.mkの
    LIBS := -llame_enc -lmp3lame
    って書くのと同じ事っぽいね。)

    で、コードはStackOverFlowに乗ってたコードをそのまま実行してみたんだが、

    FILE *pcm = fopen("file.wav", "rb");
    FILE *mp3 = fopen("file.mp3", "wb");

    const int PCM_SIZE = 1152;
    const int MP3_SIZE = 1152;

    short int pcm_buffer[PCM_SIZE*2];
    unsigned char mp3_buffer[MP3_SIZE];

    lame_t lame = lame_init();
    lame_set_in_samplerate(lame, 44100);
    lame_set_VBR(lame, vbr_default);
    lame_init_params(lame);

    fprintf(stderr,"TEST 2\n");
    do {
    read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
    fprintf(stderr,"TEST 2\n");
    if (read == 0)
    write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
    else
    write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
    fwrite(mp3_buffer, write, 1, mp3);
    } while (read != 0);

    fprintf(stderr,"TEST 3\n");
    lame_close(lame);
    fclose(mp3);
    fclose(pcm);


    これだとAndroidのAudioRecorderで録ったデータはうまく動作しなかったんだが、
    モノラルの場合初期化で設定する関数があったので呼んで、データによってlame_encode_bufferに渡す型が違う様で、正しい引数にしたらなんとかうまくいった。







  • ffmpegのソースをeclipse上で弄りたかった

    2013-11-11 02:15

    eclipseにffmpegのソースをCDTプロジェクトとしてインポートして、
    コードアシスト付きでソースを見たかったんだが、

    結論から言うとインデクサーが上手く動かなかった。

    諦めたところまでの手順
    1.Cygwinでffmpegをビルド
    2.eclipseでCDTプロジェクトを作ってインポート


    はなからeclipse上でビルドしてもいいんだろうけど(下記のやり方では./configureまでは通しておく必要がある)、
    エラーするととっても厄介そうだったので、
    取り敢えずCygwinで普通にビルドは通ることを確認してからインポートした。

    ☆Cygwinをどっかを見てインストール
    必要なのはgcc、make、tar、wget、gitくらいかな?
    他は当たり障りの無いものが入ってればOKw

    今回ffmpegに必要だったのはmp3(lame)のみで、
    他にもx264とか必要だったら入れる(簡単なので省略)

    ☆lameのインストールにnasmってのが必要らしいのでインストール
    $ wget http://www.nasm.us/pub/nasm/releasebuilds/2.10.09/nasm-2.10.09.tar.gz
    $ tar xjf nasm-2.10.09.tar.bz2
    $ cd nasm-2.10.09
    $ ./configure --prefix=/usr/local
    $ make && make install
    ☆lameをインストール
    $ wget http://downloads.sourceforge.net/lame/lame-3.99.5.tar.gz
    $ tar xzf lame-3.99.5.tar.gz
    $ cd lame-3.99.5.tar.gz
    $ ./configure prefix=/usr --enable-nasm
    $ make && make install
    通った。

    ☆ffmpegのビルド
    ※configureの改行コードをLFにするひつようがあるかもしれない
    →サクラエディタとかで開いて名前を付けて保存の時に変更とかね
    $ git clone --depth 1 git://source.ffmpeg.org/ffmpeg
    $ cd ffmpeg
    $ ./configure --prefix=/usr/local --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-pthreads --enable-libmp3lame
    $ make && make install
    通った。


    ここからが本番?
    ☆eclipse+CDTを、どっかを見てインストール

    ※プロジェクトの自動ビルド設定を外しておく
    eclipseで新規プロジェクト→C/C++をクパァしてMakefile Project with Existing Codeを選択


    プロジェクト名:適当
    Existing Code Location:ビルドしたffmpegのディレクトリまたはそれをコピーしたディレクトリのパス
    言語:C,C++両方チェック
    Toolchain for Indexer Setting:Cygwin GCC

    でできたプロジェクトをクリーン

    これで一応eclipse上でビルドが通る(自分の環境だと30分位かかるwww)んだが、
    肝心のコードアシストがおかしい。というかエラーだらけ。

    ffmpeg.cで使ってるOutputStream(struct)のbitstream_filtersってメンバが解決できない
    →これの宣言は同じ階層のffmpeg.hにあるんだけど、

    何故かlibavformat/smoothstreamingenc.cにあるOutputStreamだと勝手に解釈されて、
    そんなメンバないよとエラー表示される。ビルドは通るから、smoothstreamingenc.cにあるOutputStreamはここでは実際使われてないし、コンパイルが通る訳だから意味わからん。
    どんな風にこのstructだと決定しているのかよくわからん。

    こういうのがいーーーっぱいあって、、結局解決策がわからない。

    プロジェクトの設定の、インデクサーの設定がそれっぽいけど、
    実際にincludeしている関数のみを検出するような設定は無いっぽい。。

    ビルドが普通に通るだけに。。悔しい。。


    誰かこれを解決できた人がいたら必ず自分に教えてください。

    --------------------------------
    追記
    これこそStackOverFlowで聞いてみよ~的な何かな気がしたので聞いてみようと思ってます
    英語にするのがメンドクセーw

    聞いたら結果をここに追記します。誰も見てないだろうけどwww。