ページ 11

インラインアセンブリの基本

Posted: 2010年10月23日(土) 07:56
by みけCAT
開発環境はDev-C++4.9.9.2、コンパイラはデフォルトです。
インラインアセンブリをやってみようとしたのですが、いきなりつまずきました。
aとbの値を足してoutに代入しようとしています。
#include <stdio.h>

void test(int*,int,int);

int main(void) {
    int a;
    test(&a,10,24);
    printf("%d\n",a);
    return 0;
}

void test(int* out,int a,int b) {
    asm("movl 12(%ebp),%eax\n\t"
        "movl 16(%ebp),%ebx\n\t"
        "add %ebx,%eax\n\t"
        "movl %eax,8(%ebp)");
}
これだと0としか表示されないのですが、どうすればいいかわかりますでしょうか?
お願いします。
全くわかっていないのででたらめを書いていたらすみません。
参考にしたサイトはこれです。
http://sci10.org/on_gcc_asm.html
http://maccyo.hp.infoseek.co.jp/assembl ... embly.html

Re:インラインアセンブリの基本

Posted: 2010年10月23日(土) 13:31
by アビゲイル
    %esp   ret   &a 10   24
    (esp) 4(esp) 8(esp) 12(esp) 16(esp)
←低位    →高位(メモリ)

いじったことがないので、憶測ですが、上記のような並びになっていると思うのですが、
8(esp)の値(&a)を取り出して、その値のアドレスに代入しなければいけないのではないでしょうか?

Re:インラインアセンブリの基本

Posted: 2010年10月24日(日) 02:11
by ISLe
void test(int* out,int a,int b) {
   asm volatile (
   "movl %1,%%eax \n\t"
   "addl %2,%%eax \n\t"
   "movl %%eax,%0 \n\t"
   : "=m" (*out)
   : "r" (a), "r" (b)
   : "%eax"
   );
}
こちらの方が保守性は高いと思います。

Re:インラインアセンブリの基本

Posted: 2010年10月24日(日) 15:56
by みけCAT
#include <stdio.h>

void test(int*,int,int);

int main(void) {
    int a;
    test(&a,10,24);
    printf("%d\n",a);
    return 0;
}

void test(int* out,int a,int b) {
    asm("movl 12(%ebp),%eax\n\t"
        "movl 16(%ebp),%ebx\n\t"
        "add %ebx,%eax\n\t"
        "mov 8(%ebp),%ecx\n\t"
        "movl %eax,(%ecx)");
}
とりあえずこうしたら動きました。

ISLeさんのコードでもうまく動きました。
ありがとうございました。

Re:インラインアセンブリの基本

Posted: 2010年10月24日(日) 15:56
by みけCAT
解決し忘れました。