質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

解決済

3回答

3437閲覧

GNUアセンブリの「fild命令」や「fstep命令」の意味が分からない。

akisan55

総合スコア49

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2021/07/17 13:53

編集2021/07/17 13:56

###概要
すみません。わからないことが有るので助けてください。
以下のコードを逆アセンブリしました。

#include<stdio.h> #include<math.h> int main(void){ int s = 0; while ((++s) <= 10){ double value = s; if (s % 2 == 1){ continue; } double a; double b; double c; a = 1 / value; b = value * value; c = sqrt(value); printf("%5.1f %5.3f %6.1f %6.4f\n",value,a,b,c); } return 0; }
gcc -S -fno-asynchronous-unwind-tables -fno-ident test.c
.file "test9.c" .text .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" .align 4 LC1: .ascii "%5.1f %5.3f %6.1f %6.4f\12\0" .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $96, %esp call ___main movl $0, 92(%esp) jmp L2 L4: fildl 92(%esp) #この「fild命令」とはどういうものなのか。 fstpl 80(%esp) #この「fstep命令」とはどういうものなのか。 movl 92(%esp), %eax cltd shrl $31, %edx #多分(s % 2 == 1)を計算している。 addl %edx, %eax andl $1, %eax subl %edx, %eax cmpl $1, %eax jne L3 jmp L2 L3: fld1 #このコードの意味が分からない。 fdivl 80(%esp)  #この時、80(%esp)には何の値が入っているのかわからない。即値の$1がない? fstpl 72(%esp)     fldl 80(%esp) fmull 80(%esp)  #この時、80(%esp)には何の値が入っているのかわからない。test.cのどの部分にあたるか fstpl 64(%esp) fldl 80(%esp) fstpl (%esp) call _sqrt fstpl 56(%esp) fldl 56(%esp) fstpl 28(%esp) fldl 64(%esp) fstpl 20(%esp) fldl 72(%esp) fstpl 12(%esp) fldl 80(%esp) fstpl 4(%esp) movl $LC1, (%esp) call _printf L2: addl $1, 92(%esp) cmpl $10, 92(%esp) jle L4 movl $0, %eax leave ret .def _sqrt; .scl 2; .type 32; .endef .def _printf; .scl 2; .type 32; .endef

#わからない事
・「fld」や「fstp」、「fild」命令がどのような物なのか分かりません。
・L3の一段目の「fld1」の意味が分かりません。
・「fdiv」や「fmul」は乗除をするための命令だと思われますが、
L3の2行目の80(%esp)には何の値が入っているのでしょうか。

アセンブリ言語に詳しい方、ご教授して頂ければ、助かります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

こちらで確認するとC++コードと対応が分かるので便利です


fildl 92(%esp): 浮動小数点スタックst(0)92(%esp)を整数->不動小数変換を行いつつ積み込む
fstpl 80(%esp): 浮動小数点スタックst(0)から80(%esp)に格納する
まぁつまりは合わせてdouble value = sですね。sが整数なので変換させています。


fld1: fildl $1みたいなもん(本来fildは即値に対応していませんが)
fdivl 80(%esp): st(0) = st(0) / 80(%esp)

x87FPUはスタックマシン指向です
実際のところはスタックが伸びたりしますが面倒なのでここでは触れません。
正直デバッガでステップ実行してやるのが理解のためには一番いいと思いますよ

投稿2021/07/18 02:13

asm

総合スコア15149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akisan55

2021/07/18 08:53

一番知りたい事を教えて頂き、感謝します。 丁寧で分かりやすかったです。 compiler explorer というのも活用していきたいと思います。
guest

0

命令の動作が分からないのなら定義を読んでください。
命令名で探せば色々出てきますが、x86の基本的な命令ならとりあえずこちらのサイトがシンプルなレイアウトでおすすめです。
https://c9x.me/x86/
日本語ならこちらがそこそこちゃんとした翻訳でおすすめです。
0から作るソフトウェア開発

あとはx86のアセンブラにはAT&T記法とIntel記法の2つがあるので注意が必要です。
わかりやすく差異のまとまった日本語のサイトがどうも見つからないのですが、とりあえず英語版Wikipediaのこちらがわかりやすいかな。
x86 assembly language
オペランドのサイズがニモニックのサフィックスとして付くのが命令名を探す上でわりと注意点です。

投稿2021/07/17 14:42

ikadzuchi

総合スコア3047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akisan55

2021/07/18 08:51

有難うございます。 自分自身、どうしてもアセンブリの分かりやすいサイトを見つけられなかったので、 とても参考になりました。
guest

0

esp[a:b] は esp が指すメモリの aバイト目から(b-1)バイト目まで

esp[0:4] = printfの第1引数
esp[0:8] = sqrt の第1引数
esp[4:12] = printfの第2引数
esp[12:20] = printf の第3引数
esp[20:28] = printf の第4引数
esp[28:36] = printf の第5引数
esp[36:56] = ???
esp[56:64] = double c
esp[64:72] = double b
esp[72:80] = double a
esp[80:88] = double value
esp[88:92] = s を配置した後、 value を 8バイト境界に配置するためのパディング
esp[92:96] = int s;

asm

1 .file "test9.c" 2 .text 3 .def ___main; .scl 2; .type 32; .endef 4 .section .rdata,"dr" 5 .align 4 6LC1: 7 .ascii "%5.1f %5.3f %6.1f %6.4f\12\0" 8 .text 9 .globl _main 10 .def _main; .scl 2; .type 32; .endef 11_main: 12 pushl %ebp 13 movl %esp, %ebp 14 andl $-16, %esp # 16バイト境界に調整 15 subl $96, %esp # 自動変数領域を 96バイト確保 16 call ___main 17 movl $0, 92(%esp) # int s = 0; 18 jmp L2 # goto L2 19L4: 20 fildl 92(%esp) # double tmp = (double)s; s は esp[92:96] 21 fstpl 80(%esp) # duuble value = tmp; value は esp[80:92] 22 movl 92(%esp), %eax # int eax = s; 23 cltd # long long edx_eax = (long long)eax; 24 shrl $31, %edx # s が符号付きなので s % 2 の計算が面倒 25 addl %edx, %eax 26 andl $1, %eax 27 subl %edx, %eax # eax = s % 2 28 cmpl $1, %eax # eax と 1 を比較 29 jne L3 # if (s % 2 != 2) goto L3 30 jmp L2 # goto L2 31L3: 32 fld1 # double tmp = 1 33 fdivl 80(%esp)  # tmp /= value 34 fstpl 72(%esp) # a = tmp 35 fldl 80(%esp) # tmp = value 36 fmull 80(%esp)  # tmp *= value 37 fstpl 64(%esp) # b = tmp 38 fldl 80(%esp) # tmp = value 39 fstpl (%esp) # esp[0:8] = tmp 40 call _sqrt # tmp = call sqrt 41 fstpl 56(%esp) # c = tmp; 42 fldl 56(%esp) # tmp = c 43 fstpl 28(%esp) # esp[28:36] = tmp 44 fldl 64(%esp) # tmp = b 45 fstpl 20(%esp) # esp[20:28] = tmp 46 fldl 72(%esp) # tmp = a 47 fstpl 12(%esp) # esp[12:20] = tmp 48 fldl 80(%esp) # tmp = value 49 fstpl 4(%esp) # esp[4:12] = tmp 50 movl $LC1, (%esp) # esp[0:4] = "%5.1f %5.3f....&6.4f\n" 51 call _printf # call printfk 52L2: 53 addl $1, 92(%esp) # ++s 54 cmpl $10, 92(%esp) # s と 10 を比較 55 jle L4 # if (s <= 10) goto L4 56 movl $0, %eax # return 0; 57 leave 58 ret 59 .def _sqrt; .scl 2; .type 32; .endef 60 .def _printf; .scl 2; .type 32; .endef

投稿2021/07/18 03:29

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akisan55

2021/07/18 08:50

とても丁寧な説明、有難うございます。 それぞれの行がどこに対応しているかわかりやすかったです。 しかし、esp[36:56]は一体何に使われているのでしょうか。 分かり次第、教えて頂ければ嬉しいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問