MIRACLE
メールサービス申込 ユーザー登録 パートナー情報
お問い合わせ FAQ サイトマップ
MIRACLE LINUXの特長 製品紹介 サービス案内 購入 サポート 技術フォーラム

プロフィール

日本発のリナックス企業、ミラクル・リナックスで奮闘する社員のブログです。

ミラクル関連リンク

採用情報

サイト検索

最近のトラックバック

2008年3月

            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

« 梅雨なのに | メイン | 飲み会 »

スタックポインタの値

こんにちは。LKHSです。

自分はレジスタの中では何といっても esp (スタックポインタ)が一番好きなのですが(?)、プログラム中で esp の値を確認したい時があります。

ユーザプロセス中で esp の値を取得するには、インラインアセンブリを用いた以下のようなコードを使用してできます。

unsigned long get_esp() {
	__asm__("movl %esp, %eax");
}

int main() {
	unsigned long esp;

	esp = get_esp();
	printf("esp = 0x%08lx\n", esp);

	return 0;
}

アセンブリを確認してみます。

[...]
get_esp:
.LFB2:
        pushq  %rbp
.LCFI0:
        movq   %rsp, %rbp
.LCFI1:
#APP
        movl %esp, %eax    <= __asm__("movl %esp, %eax");
#NO_APP
        leave
        ret
[...]

ただし、これだと esp の値は get_esp() が呼び出された時の値となるので、厳密に現在の esp の値を取得するには、拡張インラインアセンブリを用いた以下のようなコードを使用すればできます。

unsigned long esp;

__asm__("movl %%esp, %0":"=g"(esp));
printf("esp = 0x%08lx\n", esp);

アセンブリを確認してみます。

[...]
main:
.LFB2:
        pushq  %rbp
.LCFI0:
        movq   %rsp, %rbp
.LCFI1:
        subq   $16, %rsp
.LCFI2:
#APP
        movl %esp, -8(%rbp)    <= __asm__("movl %%esp, %0":"=g"(esp));
#NO_APP
        movq   -8(%rbp), %rsi
        movl   $.LC0, %edi
        movl   $0, %eax
        call   printf
        movl   $0, %eax
        leave
        ret
[...]

また、カーネルコンテキスト中でユーザプロセスがシステムコールを発行した時の esp の値を取得するには、カーネルスタックに esp の値が積まれるので、以下のようなコードを使用してできます。

struct pt_regs * regs;

regs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) current->thread_info)) - 1;
printk(KERN_INFO "esp = 0x%08lx\n", regs->esp);

esp の値取り放題ですね。他にも方法ありましたら教えて下さい。

トラックバック

このページのトラックバックURL:
http://www.typepad.jp/t/trackback/4447/7036264

このページへのトラックバック一覧 スタックポインタの値:

コメント

コメントを投稿

会社情報 採用情報 個人情報保護方針 商標等取り扱い事項 English
Copyright(c)2000-2006 MIRACLE LINUX CORPORATION. All Rights Reserved.