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

プロフィール

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

ミラクル関連リンク

採用情報

サイト検索

最近のトラックバック

2008年9月

  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        

« crashコマンド ライブシステムでデバッグ | メイン | emacsの小技(4) - もう、あなたしか見えない - »

アセンブラの勉強方法 3

前回(アセンブラの勉強方法 2)の続きです。わかりづらいud2、cli、sti命令を紹介します。
初めて見ると、add、movとは違い予想しづらい命令ですが、簡単で知っていればダンプからソースのどの箇所か特定するときの助けにもなります。

まずはud2命令ですが、この命令はBUG(),BUG_ON()などで使用される命令で、パニックさせます。
free_buffer_head()を例にして見てみます(Linuxカーネル2.6.19の場合)。

<fs/buffer.c>

void free_buffer_head(struct buffer_head *bh)
{
        BUG_ON(!list_empty(&bh->b_assoc_buffers));  ・・・(1)
        kmem_cache_free(bh_cachep, bh);
        get_cpu_var(bh_accounting).nr--;
        recalc_bh_state();
        put_cpu_var(bh_accounting);
}

# objdump -d vmlinux
・・・・
c0184731 <free_buffer_head>:
c0184731:   89 c2                 mov    %eax,%edx
c0184733:   8d 40 28              lea    0x28(%eax),%eax
c0184736:   39 42 28              cmp    %eax,0x28(%edx)
c0184739:   74 08                 je     c0184743 <free_buffer_head+0x12>
c018473b:   0f 0b                 ud2a                          ・・(1)
c018473d:   8b 0b                 mov    (%ebx),%ecx
c018473f:   dc 34 33              fdivl  (%ebx,%esi,1)
c0184742:   c0 a1 a0 35 4a c0 e8  shlb   $0xe8,0xc04a35a0(%ecx)
c0184749:   10 11                 adc    %dl,(%ecx)
c018474b:   fe                    (bad) 
c018474c:   ff                    (bad) 
・・・・

objdumpコマンドでは"ud2a"と表示されていますが、これがBUGコールになります。
下記のとおりBUG_ON()のコードからud2命令を実行します。

<include/asm-generic/bug.h>

#ifndef HAVE_ARCH_BUG_ON    
#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
#endif

<include/asm-i386/bug.h>

#define BUG() __asm__ __volatile__("ud2\n")

ud2a があればBUG()コールしているとすぐわかります。
次の例はsti,cli命令です。

<kernel/softirq.c>

int on_each_cpu(void (*func) (void *info), void *info, int retry, int wait)
{
        int ret = 0;

        preempt_disable();
        ret = smp_call_function(func, info, retry, wait);
        local_irq_disable();                               ・・・(2)
        func(info);
        local_irq_enable();
        preempt_enable();                                  ・・・(3)
        return ret;
}

local_irq_enable/disable()で割り込み,許可になります。

# objdump -d vmlinux
・・・・
c0129e5a <on_each_cpu>:
c0129e5a:   57                  push   %edi
c0129e5b:   89 c7               mov    %eax,%edi
c0129e5d:   56                  push   %esi
c0129e5e:   89 d6               mov    %edx,%esi
c0129e60:   53                  push   %ebx
c0129e61:   83 ec 04            sub    $0x4,%esp
c0129e64:   8b 44 24 14         mov    0x14(%esp),%eax
c0129e68:   89 04 24            mov    %eax,(%esp)
c0129e6b:   89 f8               mov    %edi,%eax
c0129e6d:   e8 70 cc fe ff      call   c0116ae2 <smp_call_function>
c0129e72:   89 c3               mov    %eax,%ebx
c0129e74:   fa                  cli                         ・・(2)
c0129e75:   89 f0               mov    %esi,%eax
c0129e77:   ff d7               call   *%edi
c0129e79:   fb                  sti                         ・・(3)
c0129e7a:   5a                  pop    %edx
c0129e7b:   89 d8               mov    %ebx,%eax
c0129e7d:   5b                  pop    %ebx
c0129e7e:   5e                  pop    %esi
c0129e7f:   5f                  pop    %edi
c0129e80:   c3                  ret   
・・・・

<include/linux/irqflags.h>

#ifdef CONFIG_TRACE_IRQFLAGS
・・・・
#else
# define trace_hardirqs_on()            do { } while (0)
# define trace_hardirqs_off()           do { } while (0)
・・・・
#endif

#define local_irq_enable() \
        do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0)
#define local_irq_disable() \
        do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)

<include/asm-i386/irqflags.h>

static inline void raw_local_irq_disable(void)
{
        __asm__ __volatile__("cli" : : : "memory");  ・・・・(2)
}

static inline void raw_local_irq_enable(void)
{      
        __asm__ __volatile__("sti" : : : "memory");  ・・・・(3)
}

これでダンプを見ていて「ud2」「cli」「sti」などがあってもすぐにBUG、割り込みだとわかりますし、ダンプからソースのどの箇所か特定するときの助けにもなります。

トラックバック

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

このページへのトラックバック一覧 アセンブラの勉強方法 3:

コメント

コメントを投稿

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