掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.26509

C言語とアセンブラ
投稿者---ASM(2006/03/23 12:05:01)


C言語とアセンブラの対応関係についてお聞きしたいのですが
もし、わかる方は、ご指導ください。アセンブラは、MASM。
下記のC言語のサンプルは、char型の配列と整数型を宣言して
いるソースです。下記を逆アセンブルした結果がその下にある
ソースです。

buffer    = dword ptr -18h

上記の宣言は、基準ptrから18引いたところからdword確保する
と解釈してよろしいですか?

var_14    = dword ptr -14h
var_10    = dword ptr -10h
var_C      = word ptr -0Ch
var_A      = byte ptr -0Ah

上記の宣言のvar_14,var_10,var_C,var_Aというのは、何ですか?

    ; bufferに初期化済みデータを予約
    mov EAX, dword_407030
    mov [EBP+buffer], EAX
    mov ECX, dword_407034
    mov [EBP+var_14], ECX
    mov EDX, dword_407038
    mov [EBP+var_10], EDX
    xor EAX, EAX
    mov [EBP+var_C], ax
    mov [EBP+var_A], al

上記のソースは、配列に入れるための領域を確保する作業をやって
いる部分だと思うのですが、mov    EAX, dword_407030の作業は、
何をやっているのですか?dword_407030というのは、メモリのアドレス
を入れているのですか?mov  [EBP+buffer], EAXの作業についても
同じです。上記の二つでどのようなことをやったことになるのでしょうか?

上記の9行の意味をご指導ください。

/*
スタックの動作を示すためのシンプルなプログラム
*/
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    char buffer[15] = "Hello World"; /*15バイト長の文字列バッファ*/
    int int1 = 1,int2 = 2;     /*4バイト長の整数変数×2*/

    return 1;
}

逆アセンブル

_main      proc near

buffer    = dword ptr -18h
var_14    = dword ptr -14h
var_10    = dword ptr -10h
var_C      = word ptr -0Ch
var_A      = byte ptr -0Ah
int2        = dword ptr -8
int1        = dword ptr -4

    ; 関数プロローグ
    push    EBP
    mov EBP, ESP
    sub ESP, 18h
    ; bufferに初期化済みデータを予約
    mov EAX, dword_407030
    mov [EBP+buffer], EAX
    mov ECX, dword_407034
    mov [EBP+var_14], ECX
    mov EDX, dword_407038
    mov [EBP+var_10], EDX
    xor EAX, EAX
    mov [EBP+var_C], ax
    mov [EBP+var_A], al
    ; int1に初期化済みデータを予約
    mov [EBP+int1], 1
    ; int2に初期化済みデータを予約
    mov [EBP+int2], 2
    ; 戻り値をEAXに代入
    mov EAX, 1
    ; 関数エピローグ
    mov ESP, EBP
    pop EBP
    retn
_main   endp

今度は、write()関数についてなのですが、これについても
ご指導ください。

sub $0x8, %ESP
sub     $0x4, %ESP

上記でなぜ、2回に分けて領域を確保しているのですか?一度
にやるわけには、いかないのですか?

mov 0x10(%ESP,1), %EDX
mov 0xc(%ESP,1), %ECX
mov     0x8(%ESP,1), %EBX

上記の作業は、何をやっているのですか?0x10(%ESP,1)というのは
、何を表しているのでしょうか?記法がわかりません。

/*
    write()関数の動き
*/

int main()
{
    write(1,"EXAMPLE\n",10);
}

write関数をコールするmain()関数のコードの逆アセンブル

push    %EBP
mov %ESP, %EBP
sub $0x8, %ESP
sub     $0x4, %ESP
push    $0x9
push    $0x808e248
push    $0x1
call    0x804cc60 <__libc_write>
add $0x10, %ESP
leave
ret

write()関数の動作内容
push    %EBX
mov 0x10(%ESP,1), %EDX
mov 0xc(%ESP,1), %ECX
mov     0x8(%ESP,1), %EBX
mov     $0x4 %EAX
int $0x80
pop %EBX
cmp $0xfffff001, %EAX
jae 0x8052bb0 <__syscall_error>
ret

ご指導ください。聞いていない部分はわかります。



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:C言語とアセンブラ 26510 YuO 2006/03/23 12:46:51
<子記事> Re:C言語とアセンブラ 26517 si 2006/03/24 00:55:46


No.26510

Re:C言語とアセンブラ
投稿者---YuO(2006/03/23 12:46:51)


コンパイラの吐いたアセンブリ言語のソースファイルなんて,
基本的に読むものではないのですけどね……。
# コンパイラのバグを疑うときと,コンパイラの最適化以上のことをしようという無茶をしたい場合のみ。


そもそも,コンパイラが吐いたとはいえアセンブリ言語はC言語関係掲示板に書くものではないと思うのですが……。
# コンパイラのバグ,というのであれば別ですが。


buffer    = dword ptr -18h

上記の宣言は、基準ptrから18引いたところからdword確保する
と解釈してよろしいですか?


MASMにおいて,=は単にマクロ宣言だったはずです。
なので,上記はCに書き直すと,
#define buffer (dword)-0x18

に等しいことになります。


> 上記の宣言のvar_14,var_10,var_C,var_Aというのは、何ですか?

コンパイラが勝手に付けた識別子。


> 上記のソースは、配列に入れるための領域を確保する作業をやって
> いる部分だと思うのですが、mov EAX, dword_407030の作業は、
> 何をやっているのですか?dword_407030というのは、メモリのアドレス
> を入れているのですか?mov [EBP+buffer], EAXの作業についても
> 同じです。上記の二つでどのようなことをやったことになるのでしょうか?

全然違います。
スタック上に(既に)確保したbufferへの初期化作業です。
おそらく,15bytes程度であればrep movsbよりも4バイトデータの代入3回,2バイトデータの代入1回,1バイトデータの代入1回の方が速い,という判断でしょう。
dword_407030というマクロも,"hell"に相当する値が入っているはずです。


> 今度は、write()関数についてなのですが、これについても
> ご指導ください。

これは,どのコンパイラが吐いたものですか?
# 上はVCやBCCの吐くアセンブリコードっぽいですが,下はGCCの吐くアセンブリコードっぽい。


> 上記でなぜ、2回に分けて領域を確保しているのですか?一度
> にやるわけには、いかないのですか?

さぁ……?
コンパイラの制作者にでも聞いてください。

特定の実装において,なぜそのような実装になっているのかを知りたいのであれば,
実装者に聞くか,(あれば)コンパイラのソースコードを調べる以外に方法はないと思うのですが。



この投稿にコメントする

削除パスワード

No.26511

ありがとうございます
投稿者---ASM(2006/03/23 18:57:02)


お忙しい中、お答えいただきありがとうございました。

でも、なんでそんなに上から言うような感じでしか書けない
のかが、疑問だが答えてくれたのでとりあえず、ありがとう。
(これ以上思っていることを書くと喧嘩が始まるので書きません)


この投稿にコメントする

削除パスワード

No.26513

Re:ありがとうございます
投稿者---Hermit(2006/03/23 20:47:26)


普通のアドバイスに見えるけどな・・・


この投稿にコメントする

削除パスワード

No.26514

Re:ありがとうございます
投稿者---通りすがり(2006/03/23 22:26:24)


見識という点では確かに上に立っているかもしれないですけどね。


この投稿にコメントする

削除パスワード

No.26519

Re:ありがとうございます
投稿者---επιστημη(2006/03/24 06:30:38)


>でも、なんでそんなに上から言うような感じでしか書けない
>のかが、疑問だが

教える側が下手に出てどうするよ。
# 見事な回答だと思うぞ。



この投稿にコメントする

削除パスワード

No.26520

Re:ありがとうございます
投稿者---Ban(2006/03/24 14:39:44)


サポート業務で請けてるわけでもなし、普通の回答にしか見えない…。


この投稿にコメントする

削除パスワード

No.26521

Re:ありがとうございます
投稿者---RAPT(2006/03/25 00:02:29)


普通だったらむしろ「環境依存です」の一言で終わりそうなものを、
わざわざ言外の範囲まで想像して回答してもらえるなんて、
ありがたき幸せ、って思っちゃいます。自分なら。


この投稿にコメントする

削除パスワード

No.26517

Re:C言語とアセンブラ
投稿者---si(2006/03/24 00:55:46)


多分、こんな感じかと思います。
mov 0x10(%ESP,1), %EDX ; mov edx,[esp*1+16]
mov 0xc(%ESP,1) , %ECX ; mov ecx,[esp*1+12]
mov 0x8(%ESP,1) , %EBX ; mov ebx,[esp*1+8]
gccの吐いたコードですよね。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧