去年の課題です

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
丸太郎

去年の課題です

#1

投稿記事 by 丸太郎 » 12年前

コード:

$ gdb test
(gdb) disas func
Dump of assembler code for function func:
   0x080483e4 <+0>:     push   %ebp   確保
   0x080483e5 <+1>:     mov    %esp,%ebp  コピー
   0x080483e7 <+3>:     sub    $0x10,%esp  引く
   0x080483ea <+6>:     movl   $0x1,-0x4(%ebp)  ?? ①
   0x080483f1 <+13>:    movl   $0x0,-0x8(%ebp)  ??②
   0x080483f8 <+20>:    jmp    0x8048404 <func+32>  ジャンプ
   0x080483fa <+22>:    mov    -0x4(%ebp),%eax 
   0x080483fd <+25>:    add    %eax,-0x8(%ebp)
   0x08048400 <+28>:    addl   $0x1,-0x4(%ebp)
   0x08048404 <+32>:    mov    -0x4(%ebp),%eax
   0x08048407 <+35>:    cmp    0x8(%ebp),%eax  ひかく
   0x0804840a <+38>:    jle    0x80483fa <func+22> 条件満たせばじゃんぷ
   0x0804840c <+40>:    mov    -0x8(%ebp),%eax
   0x0804840f <+43>:    leave
   0x08048410 <+44>:    ret
End of assembler dump.
(gdb)
去年のもんだいです//
わかるとこかいてみました。
図を書いてみました。
http://gyazo.com/9de499e34ff42b41b699ab60b1fb75db

まず?①②がよくわからなくて mov命令で32bitまではわかるんですが。
推測としては0x1を0x4にコピーかなーとはおもうんですが、
movl $0x1,-0x4(%ebp)
$がついてたり、-がついてたり(%ebp)がついててよくわかりません。
お願いします

beatle
記事: 1281
登録日時: 13年前
住所: 埼玉
連絡を取る:

Re: 去年の課題です

#2

投稿記事 by beatle » 12年前

n(reg)は、regの値にnを足したメモリアドレスを表します。
-0x4(%ebp)
は、%ebpの値から4を引いた番地、という意味です。

丸太郎

Re: 去年の課題です

#3

投稿記事 by 丸太郎 » 12年前

beatle さんが書きました:n(reg)は、regの値にnを足したメモリアドレスを表します。
-0x4(%ebp)
は、%ebpの値から4を引いた番地、という意味です。

$0x1ていうのはアドレスか何かでしょうか?
それとも16進数の数字として扱うのでしょうか?

beatle
記事: 1281
登録日時: 13年前
住所: 埼玉
連絡を取る:

Re: 去年の課題です

#4

投稿記事 by beatle » 12年前

$は即値を表します。$nはnという整数値です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#5

投稿記事 by softya(ソフト屋) » 12年前

$で即値で、0x1で16進数のC言語で言う所の0x01です。

あと図でEPってなんでしょう? レジスタに無いんですがBPでしょうか?
それにEPが指している所が変なような。現在値なのか過去の値なのか分からないです。

次の点に気をつけてみましょう。
・メモリの下位のアドレス(値の小さい方)は通例図の上になるように書きます。
・箱1つが4バイトなのか1バイトなのかメモリとレジスタで統一しましょう。
・1から3行目の変化をうまく書けていないので、それぞれ分けて書いてみましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

丸太郎

Re: 去年の課題です

#6

投稿記事 by 丸太郎 » 12年前

softya(ソフト屋) さんが書きました:$で即値で、0x1で16進数のC言語で言う所の0x01です。

あと図でEPってなんでしょう? レジスタに無いんですがBPでしょうか?
それにEPが指している所が変なような。現在値なのか過去の値なのか分からないです。

次の点に気をつけてみましょう。
・メモリの下位のアドレス(値の小さい方)は通例図の上になるように書きます。
・箱1つが4バイトなのか1バイトなのかメモリとレジスタで統一しましょう。
・1から3行目の変化をうまく書けていないので、それぞれ分けて書いてみましょう。
epはbpの間違えですorz
それにEPが指している所が変なような。現在値なのか過去の値なのか分からないです。
>>これについてはよくわかりません。
http://www.c-tipsref.com/words/stackframe.html
ここに書かれてる以前のbpの値てことですか?
現在過去ていうのがよくわかりません。

分けてかいてみました!
http://gyazo.com/9d7e79241fbf4f9a21e60889922f5198
http://gyazo.com/5d0ed3461b2079a422d2bcef0192d95c
http://gyazo.com/8501dd81e1dd39c1d4eaaa7eabd7ae36

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#7

投稿記事 by softya(ソフト屋) » 12年前

>分けてかいてみました!
>http://gyazo.com/9d7e79241fbf4f9a21e60889922f5198
>http://gyazo.com/5d0ed3461b2079a422d2bcef0192d95c
>http://gyazo.com/8501dd81e1dd39c1d4eaaa7eabd7ae36

(1) bp,spとの関連が図から消えました。スタックメモリの4バイトが何処から来たかわかりません。
(2) spの値のコピーがbpですよね? 図では違って見えます。
(3) spやらbpが消えて謎のレジスタのようなものが書かれてますが、レジスタが1バイトなのですか?

こうしましょう。レジスタもメモリも1箱4バイトが格納されている事にしてください。ややこしいです。
それと、仮の値を決めておきましょう。
funcに来た時点で
%ebp 0x1004
%esp 0x1000
とします。図に書き入れてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

丸太郎

Re: 去年の課題です

#8

投稿記事 by 丸太郎 » 12年前

softya(ソフト屋) さんが書きました:>分けてかいてみました!
>http://gyazo.com/9d7e79241fbf4f9a21e60889922f5198
>http://gyazo.com/5d0ed3461b2079a422d2bcef0192d95c
>http://gyazo.com/8501dd81e1dd39c1d4eaaa7eabd7ae36

(1) bp,spとの関連が図から消えました。スタックメモリの4バイトが何処から来たかわかりません。
(2) spの値のコピーがbpですよね? 図では違って見えます。
(3) spやらbpが消えて謎のレジスタのようなものが書かれてますが、レジスタが1バイトなのですか?

こうしましょう。レジスタもメモリも1箱4バイトが格納されている事にしてください。ややこしいです。
それと、仮の値を決めておきましょう。
funcに来た時点で
%ebp 0x1004
%esp 0x1000
とします。図に書き入れてください。

一様書いてみました
3行目はもうわかりませんorz
http://gyazo.com/b91cf8a0fe3140cdb4f8cffb22106dfe

図ではSPとBPの値は同じで、3行目のespから10をひくっていうのはどのようなことなんでしょうか(´;ω;`)
図のどこに10バイト分かけばいいんでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#9

投稿記事 by softya(ソフト屋) » 12年前

この図だとFuncに飛び込んだ瞬間で、まだどの命令も実行されていない条件です。
ただ、spが指すスタックメモリには値が格納されています。何の値でしょうか?
あとにこの図は、1行目や2行目の動作も書き込まれていません。

ちなみに10バイト分ではなく0x10バイト分です。

うーん。こうしましょう。
アセンブラの知識が、あまりにも不十分です。
そっちの勉強からしないとダメだと思います。
かなり不満でしょうが、まず情報処理試験のCASL2のアセンブラをやってみてください。
※ 私は始めてやった時に30分マニュアル見てすぐ情報処理試験の問題が解けました。アセンブラの知識があれば簡単です。
これがクリアできたら、x86アセンブラの実習に移ります。

「CASLⅡ-目次」
http://masudahp.web.fc2.com/casl2/
「C/C++/C#/Java/BasicプログラマのためのCASL II 入門講座」
http://www.officedaytime.com/dcasl2/pguide/index.html
「CASLシミュレータ (CASL II 対応)」
http://www.officedaytime.com/dcaslj/
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

丸太郎

Re: 去年の課題です

#10

投稿記事 by 丸太郎 » 12年前

softya(ソフト屋) さんが書きました:この図だとFuncに飛び込んだ瞬間で、まだどの命令も実行されていない条件です。
ただ、spが指すスタックメモリには値が格納されています。何の値でしょうか?
あとにこの図は、1行目や2行目の動作も書き込まれていません。

ちなみに10バイト分ではなく0x10バイト分です。

うーん。こうしましょう。
アセンブラの知識が、あまりにも不十分です。
そっちの勉強からしないとダメだと思います。
かなり不満でしょうが、まず情報処理試験のCASL2のアセンブラをやってみてください。
※ 私は始めてやった時に30分マニュアル見てすぐ情報処理試験の問題が解けました。アセンブラの知識があれば簡単です。
これがクリアできたら、x86アセンブラの実習に移ります。

「CASLⅡ-目次」
http://masudahp.web.fc2.com/casl2/
「C/C++/C#/Java/BasicプログラマのためのCASL II 入門講座」
http://www.officedaytime.com/dcasl2/pguide/index.html
「CASLシミュレータ (CASL II 対応)」
http://www.officedaytime.com/dcaslj/
自分にとってはよくわからないところもありましたが、ひととおりよませていただきました。
でも実践にはいれる気がしません。
才能ないんでしょうか...
図がぜんぜんあたまに浮かびません(´;ω;`)

自分ではこれが限界です
読んでいてもよくわかりません
もう1度かいてみました
http://gyazo.com/9fa29602fa6cc2df1234c212d424358a

レジスタはどこに図を書けばいいのか?
3行目はレジスタから0x10バイトなのかスタックからなのか?
そこもわかりませんorz

1~3行目を図で表してもらえないでしょうか?

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: 去年の課題です

#11

投稿記事 by へにっくす » 12年前

丸太郎 さんが書きました:1~3行目を図で表してもらえないでしょうか?
softyaさんが理解するための基礎として挙げているのに、何でまたこういう返信になるんでしょうね。
その図を提示したところで、本当の理解にはつながらないから、まずはCASL IIのサイトをみてという流れになっているのにさあ。
一通り読んで分からなければ、まずどこが分からないかを聞くべきだと思いますよ?
オフトピック
才能ないと言ってますけどね、たった2時間で分かるわけないでしょう。
世の中には見ただけで分かる人もいますが、大抵は何年かかけて才能を開花させる人がほとんどです。
written by へにっくす

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#12

投稿記事 by softya(ソフト屋) » 12年前

いきなり、ややこしいx86アセンブラをを理解できるのは余程の人です。
あと電子回路やデジタル回路の経験があるか無いかでも理解度は変わってくると思います。
つまり、それだけハード側の技術なのです。

なので、よりシンプルで簡単なCASL2を紹介したわけです。

>自分にとってはよくわからないところもありましたが、ひととおりよませていただきました。
>でも実践にはいれる気がしません。
>才能ないんでしょうか...
>図がぜんぜんあたまに浮かびません(´;ω;`)

私がCASLを30分で理解できたのは、それまで様々なアセンブラを使いこなしていたからです。
つまり、アセンブラの基礎力があったのです。
それが無いと30分や1時間では無理です。
ただ、それでもCASL2はすごく簡単なのです。

まず、CASL2が軽くこなせないとx86アセンブラは無理だと思います。
修行のためにもCASL2をやって欲しいです。
回り道に見えるかもしれませんが、x86を理解するにはこちらからのほうが早いと思います。

あと一箱4バイトの約束だったのに4個の箱があるので読み落としているんじゃと思います。
図の間違いを指摘すると0x1000から0x1003までのアドレスでは箱は1個であり0x1004の分を書いても箱は2つです。
あとスタックメモリとレジスタが分けて書かれていません。かなり混乱が見られます。
私が書いた0x1000とか0x1004はレジスタの値ですよ。

ね。CASL2からしませんか?
CASL2シミュレータはメモリとレジスタの変化が見られるのでお勧めです。
と言いながら、さっきのシミュレータがスタック非表示だったのに気づきました。
2つ紹介しますので、お好きな方をどうぞ。
「InfoCASL Home Page」
http://www.rs.kagu.sut.ac.jp/~infoserv/ ... /infocasl/
「WCASL Ⅱ」
http://www.ics.teikyo-u.ac.jp/wcasl2/
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

丸太郎

Re: 去年の課題です

#13

投稿記事 by 丸太郎 » 12年前

へにっくす さんが書きました:
丸太郎 さんが書きました:1~3行目を図で表してもらえないでしょうか?
softyaさんが理解するための基礎として挙げているのに、何でまたこういう返信になるんでしょうね。
その図を提示したところで、本当の理解にはつながらないから、まずはCASL IIのサイトをみてという流れになっているのにさあ。
一通り読んで分からなければ、まずどこが分からないかを聞くべきだと思いますよ?
オフトピック
才能ないと言ってますけどね、たった2時間で分かるわけないでしょう。
世の中には見ただけで分かる人もいますが、大抵は何年かかけて才能を開花させる人がほとんどです。

もう寝ずに40時間近くずっと格闘してるんですが...
2時間じゃねーし(´・д・`)
だからわからないところをいったじゃないですか...
レジスタがわからないんです 
ここで聞くのは諦めます。 あとすこしのところまできてるからこそ図をたのんでいるのに..

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#14

投稿記事 by softya(ソフト屋) » 12年前

まず眠りましょう。寝不足は学習に良いことなんてありません。
理解力は相当低下しているはずです。

また、明日考えてみましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

丸太郎

Re: 去年の課題です

#15

投稿記事 by 丸太郎 » 12年前

softya(ソフト屋) さんが書きました:いきなり、ややこしいx86アセンブラをを理解できるのは余程の人です。
あと電子回路やデジタル回路の経験があるか無いかでも理解度は変わってくると思います。
つまり、それだけハード側の技術なのです。

なので、よりシンプルで簡単なCASL2を紹介したわけです。

>自分にとってはよくわからないところもありましたが、ひととおりよませていただきました。
>でも実践にはいれる気がしません。
>才能ないんでしょうか...
>図がぜんぜんあたまに浮かびません(´;ω;`)

私がCASLを30分で理解できたのは、それまで様々なアセンブラを使いこなしていたからです。
つまり、アセンブラの基礎力があったのです。
それが無いと30分や1時間では無理です。
ただ、それでもCASL2はすごく簡単なのです。

まず、CASL2が軽くこなせないとx86アセンブラは無理だと思います。
修行のためにもCASL2をやって欲しいです。
回り道に見えるかもしれませんが、x86を理解するにはこちらからのほうが早いと思います。

あと一箱4バイトの約束だったのに4個の箱があるので読み落としているんじゃと思います。
図の間違いを指摘すると0x1000から0x1003までのアドレスでは箱は1個であり0x1004の分を書いても箱は2つです。
あとスタックメモリとレジスタが分けて書かれていません。かなり混乱が見られます。
私が書いた0x1000とか0x1004はレジスタの値ですよ。

ね。CASL2からしませんか?
CASL2シミュレータはメモリとレジスタの変化が見られるのでお勧めです。
と言いながら、さっきのシミュレータがスタック非表示だったのに気づきました。
2つ紹介しますので、お好きな方をどうぞ。
「InfoCASL Home Page」
http://www.rs.kagu.sut.ac.jp/~infoserv/ ... /infocasl/
「WCASL Ⅱ」
http://www.ics.teikyo-u.ac.jp/wcasl2/

よみましたよ、でもレジスタとスタックについて全然かかれてるところなかった気がするんですが...

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: 去年の課題です

#16

投稿記事 by へにっくす » 12年前

丸太郎 さんが書きました:もう寝ずに40時間近くずっと格闘してるんですが...
2時間じゃねーし(´・д・`)
softyaさんが投稿(6/2 21:58)して、貴方が返信した(6/2 23:58)のが2時間なのでそう指摘したまでです。
それに40時間寝ずにいること自体が変です。1日で何もかもできるわけないでしょ。
まずは基礎を学んでください。
最後に編集したユーザー へにっくす on 2013年6月03日(月) 01:14 [ 編集 3 回目 ]
written by へにっくす

丸太郎

Re: 去年の課題です

#17

投稿記事 by 丸太郎 » 12年前

へにっくす さんが書きました:
丸太郎 さんが書きました:もう寝ずに40時間近くずっと格闘してるんですが...
2時間じゃねーし(´・д・`)
softyaさんが投稿(6/2 21:58)して、貴方が返信した(6/2 23:58)のが2時間なのでそう指摘したまでです。
それに40時間寝ずにいること自体が変です。1日で何もかもできるわけないでしょ。
まずは基礎を学んでください。

それだけ面白いからずっといろいろしらべたりしてやっているんです?変ですか? 
2時間よりも前から同じようなこと聴いたりしてますよね? ほかのすれで?頭やわらかくして考えてよ。

だからさ図書いてくれたら逆算できるよね 「ここがこうなってるからこうなるのか!て。」 わからない問題を答えも見ないでずっと考えてるほうが効率がわるいとおもいますよ。数学とかでわからなかったら答えから逆算しますよね。

あなたは図がかけないんですかね? 理解できてないならしょうがないですが..

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 去年の課題です

#18

投稿記事 by ISLe » 12年前

丸太郎 さんが書きました:レジスタがわからないんです 
ここで聞くのは諦めます。 あとすこしのところまできてるからこそ図をたのんでいるのに..
レジスタだけじゃなく記憶装置全般分かってないように見えますけど。
あとすこしではないです。
すこしも分かってないです。
分かってないことが分かってないですね。
丸太郎 さんが書きました:よみましたよ、でもレジスタとスタックについて全然かかれてるところなかった気がするんですが...
レジスタとメモリについて書かれたページ
http://masudahp.web.fc2.com/casl2/casl2010.html
スタックについて書かれたページ
http://masudahp.web.fc2.com/casl2/casl2160.html

むしろどうしたら見逃せるのでしょうか。

丸太郎

Re: 去年の課題です

#19

投稿記事 by 丸太郎 » 12年前

ISLe さんが書きました:
丸太郎 さんが書きました:レジスタがわからないんです 
ここで聞くのは諦めます。 あとすこしのところまできてるからこそ図をたのんでいるのに..
レジスタだけじゃなく記憶装置全般分かってないように見えますけど。
あとすこしではないです。
すこしも分かってないです。
分かってないことが分かってないですね。
丸太郎 さんが書きました:よみましたよ、でもレジスタとスタックについて全然かかれてるところなかった気がするんですが...
レジスタとメモリについて書かれたページ
http://masudahp.web.fc2.com/casl2/casl2010.html
スタックについて書かれたページ
http://masudahp.web.fc2.com/casl2/casl2160.html

むしろどうしたら見逃せるのでしょうか。

確かにcははじめてそんなになのでわかっていないかもしれません。
さきほどもこちらのページは読ませていただきましたが、もう1度しっかり読ませていただきます。

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: 去年の課題です

#20

投稿記事 by へにっくす » 12年前

丸太郎 さんが書きました:それだけ面白いからずっといろいろしらべたりしてやっているんです?変ですか? 
2時間よりも前から同じようなこと聴いたりしてますよね? ほかのすれで?頭やわらかくして考えてよ。

だからさ図書いてくれたら逆算できるよね 「ここがこうなってるからこうなるのか!て。」 わからない問題を答えも見ないでずっと考えてるほうが効率がわるいとおもいますよ。数学とかでわからなかったら答えから逆算しますよね。

あなたは図がかけないんですかね? 理解できてないならしょうがないですが..
こんな回答がくるとは、学ぼうと言う姿勢がないということですね。
そこまで言うなら、もう私からは何も言うことはありません。どうぞ勝手になさってください。
written by へにっくす

丸太郎

Re: 去年の課題です

#21

投稿記事 by 丸太郎 » 12年前

へにっくす さんが書きました:
丸太郎 さんが書きました:それだけ面白いからずっといろいろしらべたりしてやっているんです?変ですか? 
2時間よりも前から同じようなこと聴いたりしてますよね? ほかのすれで?頭やわらかくして考えてよ。

だからさ図書いてくれたら逆算できるよね 「ここがこうなってるからこうなるのか!て。」 わからない問題を答えも見ないでずっと考えてるほうが効率がわるいとおもいますよ。数学とかでわからなかったら答えから逆算しますよね。

あなたは図がかけないんですかね? 理解できてないならしょうがないですが..
こんな回答がくるとは、学ぼうと言う姿勢がないということですね。
そこまで言うなら、もう私からは何も言うことはありません。
どこから学ぼうろする姿勢がないとおもったのかな?
ただ自分がおもうことを書いただけですけどね。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 去年の課題です

#22

投稿記事 by ISLe » 12年前

丸太郎 さんが書きました:確かにcははじめてそんなになのでわかっていないかもしれません。
cってC言語のことですか?
アセンブラはC言語の知識では読めませんよ。
ハードウェアレベルの知識が必要ですから。
ポインタ関連でアドレスを実際のハードウェアに喩える説明がよく見られますがあれはむしろ混乱の元だと思います。


レジスタはCPUの中にある一時メモリです。
レジスタとメモリ(メインメモリ/システムメモリとも言う)は別モノです。
スタックはメモリ上の特定の領域です。

なので、スタックフレームを図にすると、連続したメモリを別の場所にあるレジスタが指す形になります。

レジスタが指している場所はどこか。
スタックとはどこのことか。
その周辺のメモリがどのように使われるか。
を考えてみてください。

本当にアセンブラに興味があるなら、きちんと勉強したほうが近道だと思いますけど。

(追記を消して戻しました)
最後に編集したユーザー ISLe on 2013年6月03日(月) 01:39 [ 編集 2 回目 ]

丸太郎

Re: 去年の課題です

#23

投稿記事 by 丸太郎 » 12年前

ISLe さんが書きました:
丸太郎 さんが書きました:確かにcははじめてそんなになのでわかっていないかもしれません。
cってC言語のことですか?
アセンブラはC言語の知識では読めませんよ。
ハードウェアレベルの知識が必要ですから。
ポインタ関連でアドレスを実際のハードウェアに喩える説明がよく見られますがあれはむしろ混乱の元だと思います。


レジスタはCPUの中にある一時メモリです。
レジスタとメモリ(メインメモリ/システムメモリとも言う)は別モノです。
スタックはメモリ上の特定の領域です。

なので、スタックフレームを図にすると、連続したメモリを別の場所にあるレジスタが指す形になります。

レジスタが指している場所はどこか。
スタックとはどこのことか。
その周辺のメモリがどのように使われるか。
を考えてみてください。

本当にアセンブラに興味があるなら、きちんと勉強したほうが近道だと思いますけど。
レジスタはCPUの中にある一時メモリです。
レジスタとメモリ(メインメモリ/システムメモリとも言う)は別モノです。
スタックはメモリ上の特定の領域です。
なので、スタックフレームを図にすると、連続したメモリを別の場所にあるレジスタが指す形になります。
>>この文とてもわかりやすいです!!!!!!!!!
特定の領域というのは、具体的にどんなところですか?gdbででた結果の左にあるアドレスが関わっているのですか?
またspとbpはレジスタのことですよね?

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 去年の課題です

#24

投稿記事 by ISLe » 12年前

丸太郎 さんが書きました:特定の領域というのは、具体的にどんなところですか?gdbででた結果の左にあるアドレスが関わっているのですか?
それはsoftyaさんが紹介してくれたCASLⅡのテキスト(特にあとからわたしがリンクしたページ)を読めば書いてありますけど。
丸太郎 さんが書きました:またspとbpはレジスタのことですよね?
どこの話ですか?
とりあえず最初の質問に書かれたアセンブラコードで頭に%が付いているのはレジスタです。
アセンブラという統一された言語があるわけではないので、どこのアセンブラの話か明示してもらわないと通じないです。



プログラムを追いながら図を書くとき、レジスタやメモリの内容が変わったら、図をコピーして変化した部分を書き換えていくようにすると良いです。
変化を目に見えるようにすることで理解が進みます。

丸太郎

Re: 去年の課題です

#25

投稿記事 by 丸太郎 » 12年前

ISLe さんが書きました:
丸太郎 さんが書きました:特定の領域というのは、具体的にどんなところですか?gdbででた結果の左にあるアドレスが関わっているのですか?
それはsoftyaさんが紹介してくれたCASLⅡのテキスト(特にあとからわたしがリンクしたページ)を読めば書いてありますけど。
丸太郎 さんが書きました:またspとbpはレジスタのことですよね?
どこの話ですか?
とりあえず最初の質問に書かれたアセンブラコードで頭に%が付いているのはレジスタです。
アセンブラという統一された言語があるわけではないので、どこのアセンブラの話か明示してもらわないと通じないです。



プログラムを追いながら図を書くとき、レジスタやメモリの内容が変わったら、図をコピーして変化した部分を書き換えていくようにすると良いです。
変化を目に見えるようにすることで理解が進みます。

いま自分の中でわからないことは、

コード:

0x080483e4 <+0>:     push   %ebp   確保
0x080483e5 <+1>:     mov    %esp,%ebp  コピー
0x080483e7 <+3>:     sub    $0x10,%esp  引く 
というアセンブリがあったときに、
①どこがレジスタの変化なのか?スタックの変化なのか?
②図に表して変化を書くときにレジスタとスタックの位置関係が...??

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#26

投稿記事 by softya(ソフト屋) » 12年前

>①どこがレジスタの変化なのか?スタックの変化なのか?
>②図に表して変化を書くときにレジスタとスタックの位置関係が...??

それではハードウェア的なことや命令の動作がまったく理解できていない事になります。
CASL2を無視して話を進めたいみたいですが、現状はx86は無理だと思います。
ISLeさんの言われるように、まったくレジスタとメモリの関係を理解されていません。
ちゃんと理解するためにCASL2をやってください。
回り道に見えても、そらが一番の近道です。
レジスタやメモリをちゃんと理解しましょう。

【補正】
それとアセンブラをやるのにCの知識は不要です。
Cと絡めて考える時には必要ですが、それはアセンブラを理解してからです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

non
記事: 1097
登録日時: 14年前

Re: 去年の課題です

#27

投稿記事 by non » 12年前

盛り上がっていて楽しそうですね。急がば回れという言葉はありますが、いざそれを実践するのはなかなか困難なことですよね。
力になってあげたいけど、私は8086系のアセンブラなんて知りませんのでね。CASL2でなく、CASLならわかるけど。(古いね)

横から、便乗質問させてもらって悪いけど、
3行目の sub $0x10,%esp で、 なぜ、0x10バイトなのでしょうか?
ローカル変数として4バイトが2個あるようですから、8バイト分はわかりますが。
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#28

投稿記事 by softya(ソフト屋) » 12年前

non さんが書きました:横から、便乗質問させてもらって悪いけど、
3行目の sub $0x10,%esp で、 なぜ、0x10バイトなのでしょうか?
ローカル変数として4バイトが2個あるようですから、8バイト分はわかりますが。
gccの詳しく仕様がわからないですが、なぜか8バイト余分にスタックフレームを生成している様に見えますね。
作業領域用?とか思うのですが使っていないのに確保されるのは謎です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

non
記事: 1097
登録日時: 14年前

Re: 去年の課題です

#29

投稿記事 by non » 12年前

そうですか。わかりました。ありがとうございます。
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#30

投稿記事 by softya(ソフト屋) » 12年前

non さんが書きました:そうですか。わかりました。ありがとうございます。
試しにローカル変数を4個に増やしてもsub $0x10,%espのままでした。
つまり、16バイトバウンダリに拘っているようです。 【訂正】バウンダリではなく16バイトの単位と言ったほうが良いです。
ちなみにローカル変数を5個に増やすとsub $0x20,%espとなります。
オプティマイズすれば全然違うコードになるんですけどね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

non
記事: 1097
登録日時: 14年前

Re: 去年の課題です

#31

投稿記事 by non » 12年前

なるほど、16の倍数ですか。了解です。
non

丸太郎

Re: 去年の課題です

#32

投稿記事 by 丸太郎 » 12年前

softya(ソフト屋) さんが書きました:>①どこがレジスタの変化なのか?スタックの変化なのか?
>②図に表して変化を書くときにレジスタとスタックの位置関係が...??

それではハードウェア的なことや命令の動作がまったく理解できていない事になります。
CASL2を無視して話を進めたいみたいですが、現状はx86は無理だと思います。
ISLeさんの言われるように、まったくレジスタとメモリの関係を理解されていません。
ちゃんと理解するためにCASL2をやってください。
回り道に見えても、そらが一番の近道です。
レジスタやメモリをちゃんと理解しましょう。

【補正】
それとアセンブラをやるのにCの知識は不要です。
Cと絡めて考える時には必要ですが、それはアセンブラを理解してからです。
理解しようとしてきのう貼られていたurlを見ていますが、レジスタとスタックの位置関係が書かれてるサイトなどはないでしょうか?
cpuにレジスタがありメモリーにスタックがあるとこまでは理解してます。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#33

投稿記事 by softya(ソフト屋) » 12年前

位置関係ですか?
簡単になら書いたのが準備してありますが、これ以上の関連性は無いと思ってください。
レジスタの値がアドレスとして使われるのか、単なるデータ値とし使われるのかは命令次第です。
つまり、絶対な関係はありません。
一般的なCPUの概念図.png
一般的なCPUの概念図.png (13.07 KiB) 閲覧数: 11868 回
あとCASL2をやるというのはx86の理解を一時保留して欲しいという意味ですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

丸太郎

Re: 去年の課題です

#34

投稿記事 by 丸太郎 » 12年前

softya(ソフト屋) さんが書きました:位置関係ですか?
簡単になら書いたのが準備してありますが、これ以上の関連性は無いと思ってください。
レジスタの値がアドレスとして使われるのか、単なるデータ値とし使われるのかは命令次第です。
つまり、絶対な関係はありません。
一般的なCPUの概念図.png
あとCASL2をやるというのはx86の理解を一時保留して欲しいという意味ですよ。

ほかのサイトを読んでいて理解しました。
自分は深く考えすぎてたようです。
すべてを理解するのは不可能にきまってますし、
1~3行目では大まかにいえば40バイト分スタックに..と考えればいいんですね。
1~2まではまだよくわかりませんが、掲示板で聞いてても、なかなか難しいので知り合いの人に聞いてみます。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 去年の課題です

#35

投稿記事 by ISLe » 12年前

丸太郎 さんが書きました:①どこがレジスタの変化なのか?スタックの変化なのか?
②図に表して変化を書くときにレジスタとスタックの位置関係が...??
pushというのは、
1.スタックポインタ(%esp)を、オペランド対象のレジスタ(ここでは%ebp:4バイト)のサイズ分、減じる
2.オペランド対象のレジスタの持つ値を、スタックポインタの指すアドレスから、メモリに書き込む
という命令です。
つまり最初の一命令だけでレジスタもメモリも変化し、結果としてスタックも変化します。
要するに全部変化します。

push命令を理解して図を描けるようになったらあとは難しくないような気がしますけど。

参考:CASL2スタックについて書かれたページ
http://masudahp.web.fc2.com/casl2/casl2160.html
CASL2ではスタックの先頭をスタックトップと呼ぶらしいですが、x86(実際にはCASL2も)スタックはメモリの下位アドレスに向かって伸びていきます。

丸太郎

Re: 去年の課題です

#36

投稿記事 by 丸太郎 » 12年前

ISLe さんが書きました:
丸太郎 さんが書きました:①どこがレジスタの変化なのか?スタックの変化なのか?
②図に表して変化を書くときにレジスタとスタックの位置関係が...??
pushというのは、
1.スタックポインタ(%esp)を、オペランド対象のレジスタ(ここでは%ebp:4バイト)のサイズ分、減じる
2.オペランド対象のレジスタの持つ値を、スタックポインタの指すアドレスから、メモリに書き込む
という命令です。
つまり最初の一命令だけでレジスタもメモリも変化し、結果としてスタックも変化します。
要するに全部変化します。

push命令を理解して図を描けるようになったらあとは難しくないような気がしますけど。

参考:CASL2スタックについて書かれたページ
http://masudahp.web.fc2.com/casl2/casl2160.html
CASL2ではスタックの先頭をスタックトップと呼ぶらしいですが、x86(実際にはCASL2も)スタックはメモリの下位アドレスに向かって伸びていきます。

pushやpopやsubはスタックを変化させるということでしょうか?

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 去年の課題です

#37

投稿記事 by ISLe » 12年前

丸太郎 さんが書きました:1~3行目では大まかにいえば40バイト分スタックに..と考えればいいんですね。
どのように理解しているのか分からないので違うとも言い切れないですが。
そこをきちんと理解しないと何のためにアセンブラ勉強するのやらじゃないですかね。

スタックを広げて自由に使える領域(スタックフレーム)を確保しているんですよ。
どうしてそこが自由に使える領域なのか理解する必要があると思いますけどね。
そうでないと%ebpのオフセットでメモリにアクセスしている理由も理解できないでしょう。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 去年の課題です

#38

投稿記事 by ISLe » 12年前

丸太郎 さんが書きました:pushやpopやsubはスタックを変化させるということでしょうか?
pushは全部変化するとはっきり書きました。
とうぜん対になるpopもです。

subはスタックを変化させるとは限りません。
減算対象がスタックポインタなら変化するでしょう。
理由はわたしが何度もリンクを張っているページを読めば分かりますね。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 去年の課題です

#39

投稿記事 by softya(ソフト屋) » 12年前

> pushやpopやsubはスタックを変化させるということでしょうか?

pushやpopの特殊動作をするものとsubを同一に扱うのは間違っています。
命令の説明書を読んだ事がないとしか思えませんので、ちゃんと読んでください。
アセンブラを勉強しているんですから読まずに済ませていけません。

「日本語技術資料のダウンロード」
http://www.intel.co.jp/content/www/jp/j ... nload.html
ここの
IA-32 インテル® アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、中巻 A: 命令セット・リファレンス A-M [日本語: PDF 形式 5,251 KB]
IA-32 インテル® アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、中巻 B: 命令セット・リファレンス N-Z [日本語: PDF 形式 4,215 KB]
です。なおアセンブラはINTEL記法なので、AT&T記法のgccとは違います。
AT&T記法の命令説明書は見つけられませんでした。
非表示エリア
この非表示エリアを表示するには、登録し、ログインする必要があります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

丸太郎

Re: 去年の課題です

#40

投稿記事 by 丸太郎 » 12年前

ISLe さんが書きました:
丸太郎 さんが書きました:1~3行目では大まかにいえば40バイト分スタックに..と考えればいいんですね。
どのように理解しているのか分からないので違うとも言い切れないですが。
そこをきちんと理解しないと何のためにアセンブラ勉強するのやらじゃないですかね。

スタックを広げて自由に使える領域(スタックフレーム)を確保しているんですよ。
どうしてそこが自由に使える領域なのか理解する必要があると思いますけどね。
そうでないと%ebpのオフセットでメモリにアクセスしている理由も理解できないでしょう。

いろいろやってるうちに溜まった知識がかさなって「あっ」てわかる日が来るとおもうんです。

丸太郎

Re: 去年の課題です

#41

投稿記事 by 丸太郎 » 12年前

ISLe さんが書きました:
丸太郎 さんが書きました:pushやpopやsubはスタックを変化させるということでしょうか?
pushは全部変化するとはっきり書きました。
とうぜん対になるpopもです。

subはスタックを変化させるとは限りません。
減算対象がスタックポインタなら変化するでしょう。
理由はわたしが何度もリンクを張っているページを読めば分かりますね。
それがなんど読んでもわからないので聞いているんですよね。
馬鹿ですいませんねorz

non
記事: 1097
登録日時: 14年前

Re: 去年の課題です

#42

投稿記事 by non » 12年前

丸太郎さんこんにちは。

> pushやpopやsubはスタックを変化させるということでしょうか?
スタックって書かずに、スタックポインタかスタック領域(スタックフレーム)か区別して質問してくださいね。
non

かずま

Re: 去年の課題です

#43

投稿記事 by かずま » 12年前

softya(ソフト屋) さんが書きました: 試しにローカル変数を4個に増やしてもsub $0x10,%espのままでした。
つまり、16バイトバウンダリに拘っているようです。 【訂正】バウンダリではなく16バイトの単位と言ったほうが良いです。
ちなみにローカル変数を5個に増やすとsub $0x20,%espとなります。
オプティマイズすれば全然違うコードになるんですけどね。
GCCコマンド・オプション -mpreferred-stack-boundary=num で指定できます。

http://www.asahi-net.or.jp/~wg5k-ickw/h ... gcc_2.html

-mpreferred-stack-boundary=num

スタック境界を、 2をnum乗したバイト数単位に境界整列します。
`-mpreferred-stack-boundary'が指定されない場合のデフォルト値
は 4(16バイト、あるいは、128ビット)です。スタックは4バイト
境界に整列される必要があります。また、PentiumとPentiumProでは、
doubleとlong doubleの値は8バイト境界に整列しなければなりません
(`-malign-double'を参照)。さもないと、実行時の性能に重大な
影響が出ます。 Pentium IIIでは、Streaming SIMD Extention(SSE)
のデータ型である__m128が16バイト境界に整列されていない場合に、
同様の影響が出ます。これらの値がスタック上において適切な境界に
整列されることを確実にするためには、 スタック境界そのものが、
そのスタック上に格納される可能性のある値が要求する最大の境界に
整列されていなければなりません。さらにすべての関数が、スタック
が常に境界整列されるように、 生成されなければなりません。より
大きいスタック境界値を指定してコンパイルされた関数を、より小
さいスタック境界値を指定してコンパイルされた関数から呼び出すと、
ほとんどの場合、境界整列が正しくなくなります。コールバックを
使うライブラリでは、常にデフォルトの設定を使うようお勧めします。
この余分の境界整列は余分のスタック領域を消費します。組み込み
システムやオペレーティング・システムのカーネルのようにスタック
領域の使用に敏感なコードでは、`-mpreferred-stack-boundary=2'に
よって希望する境界整列の値を小さくすることもできます。

non
記事: 1097
登録日時: 14年前

Re: 去年の課題です

#44

投稿記事 by non » 12年前

かずまさん
詳しい説明ありがとうございます。
non

かずま

Re: 去年の課題です

#45

投稿記事 by かずま » 12年前

コード:

---------------------------------------------------------
レジスタ
 %eax:  xxxxxxxx
 %ebx:  xxxxxxxx
 %ecx:  xxxxxxxx
 %edx:  xxxxxxxx
 %edi:  xxxxxxxx
 %esi:  xxxxxxxx
 %ebp:  0bff1c24               ベースポインタ(フレームポインタ)
 %esp:  0bff1c14               スタックポインタ
 %eip:  080483e4 ->080483e5    命令ポインタ(プログラムカウンタ)

---------------------------------------------------------
メモリ(コード領域の抜粋)
 関数 func のコード
 080483e4 < +0>:  55                      push   %ebp
 080483e5 < +1>:  89 e5                   mov    %esp,%ebp
 080483e7 < +3>:  83 ec 10                sub    $0x10,%esp
 080483ea < +6>:  c7 45 fc 01 00 00 00    movl   $0x1,-0x4(%ebp)
 080483f1 <+13>:  c7 45 f8 00 00 00 00    movl   $0x0,-0x8(%ebp)
 080483f8 <+20>:  eb 0a                   jmp    0x8048404 <f+32>
 080483fa <+22>:  8b 45 fc                mov    -0x4(%ebp),%eax
 080483fd <+25>:  01 45 f8                add    %eax,-0x8(%ebp)
 08048400 <+28>:  83 45 fc 01             addl   $0x1,-0x4(%ebp)
 08048404 <+32>:  8b 45 fc                mov    -0x4(%ebp),%eax
 08048407 <+35>:  3b 45 08                cmp    0x8(%ebp),%eax
 0804840a <+38>:  7e ed                   jle    0x80483fa <func+22>
 0804840c <+40>:  8b 45 f8                mov    -0x8(%ebp),%eax
 0804840f <+43>:  c9                      leave  
 08048410 <+44>:  c3                      ret    

---------------------------------------------------------
メモリ(スタック領域の抜粋)
 0bff1c00: xxxxxxxx   境界調整(使用されない)
 0bff1c04: xxxxxxxx   境界調整(使用されない)
 0bff1c08: xxxxxxxx   ローカル変数その2 [-8(%ebp)]
 0bff1c0c: xxxxxxxx   ローカル変数その1 [-4(%ebp)]
 0bff1c10: xxxxxxxx   一つ前にスタックフレームの ebp
 0bff1c14: 08048516   func からの return address
 0bff1c18: 0000000a   func の引数 10
---------------------------------------------------------

push %ebp を実行すると、
レジスタ %esp の値が 4減って 0bff1c10 になり、
メモリ 0bff1c10 の値が %ebp の値と同じ 0bff1c24 になる。

mov %esp,%ebp を実行すると、
レジスタ %ebp の値が %esp の値と同じ 0bff1c10 になる。

sub $0x10,%esp を実行すると、
レジスタ %esp の値が 16減って、0bff1c00 になる。

movl $0x1,-0x4(%ebp) を実行すると、
メモリ 0bff1c0c (%ebp - 4) の値が、1 になる。

movl $0x0,-0x8(%ebp) を実行すると、
メモリ 0bff1c08 (%ebp - 8) の値が、0 になる。

閉鎖

“C言語何でも質問掲示板” へ戻る