mikecat_mixc 2013-09-10 09:49:43

[C] 目的を忘れるな このエントリーをはてなブックマークに追加

投稿者からのアピールポイント

gccの拡張インラインアセンブリを使うとき、バージョンによってはスタックを使って%espの値を変えるとパラメータで指定したメモリのアドレスがずれ、参照できなくなってしまうので、 データをあらかじめスタック領域に積んで退避しておくことにしました。

実際に使うコードでは、データを積む分だけでなく、作業用メモリとして使うスタック領域もあらかじめ確保し、push/popはしないようにします。

/* この環境のunsigned intは4バイト */
unsigned int hoge,fuga,foo,bar;

/* 間違い */
__asm__ volatile (
	/* データの退避 */
	"pushl %3\n\t"
	"pushl %2\n\t"
	"pushl %1\n\t"
	"pushl %0\n\t"

	/* 処理を行う */

	/* スタックを戻す */
	"pop %%eax\n\t"
	"pop %%eax\n\t"
	"pop %%eax\n\t"
	"pop %%eax\n\t"
: /* no output */
: "m"(hoge),"m"(fuga),"m"(foo),"m"(bar)
: "%eax","%ebx","%ecx","%edx","%esi","%edi"
);

/* 正解例 */
__asm__ volatile (
	/* データの退避 */
	"mov %0,%%eax\n\t"
	"mov %1,%%ecx\n\t"
	"mov %2,%%edx\n\t"
	"mov %3,%%ebx\n\t"
	"sub $16,%%esp\n\t"
	"mov %%eax,(%%esp)\n\t"
	"mov %%ecx,4(%%esp)\n\t"
	"mov %%edx,8(%%esp)\n\t"
	"mov %%ebx,12(%%esp)\n\t"

	/* 処理を行う */

	/* スタックを戻す */
	"add $16,%%esp\n\t"
: /* no output */
: "m"(hoge),"m"(fuga),"m"(foo),"m"(bar)
: "%eax","%ebx","%ecx","%edx","%esi","%edi"
);

コメント

まだコメントがありません。最初にコメントを残しませんか?