teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

P.S.追記

2019/10/23 22:19

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -17,4 +17,18 @@
17
17
 
18
18
  と割り当てています。これがわかれば leal 22(%esp), %eax が sample 配列の先頭アドレスを求めているとわかります。
19
19
 
20
- ローカル変数は「スタックポインタ+オフセット」が、その変数のアドレスになることを、当然ながらコンパイラは分かったうえでコードを生成するので、アセンブリコードに変数名を出力することは、まずありません。
20
+ ローカル変数は「スタックポインタ+オフセット」が、その変数のアドレスになることを、当然ながらコンパイラは分かったうえでコードを生成するので、アセンブリコードに変数名を出力することは、まずありません。
21
+
22
+ P.S.
23
+ コンパイルが通っただけでは正しい動作にならないことがたくさんあったはずです。動作しているように見えても、実はおかしな動作をしていた、という経験はありませんでしたか?scanf() が正しく動作したとは、入力したものが期待どおりに変数に格納されたかどうか、結果を確認できて初めて動作できたと言えます。例えば
24
+ ```C
25
+ char buffer[10];
26
+ scanf("%s", buffer); // 入力したものが
27
+ printf("[%s]\n", buffer); // 格納されたか確認
28
+ ```
29
+ アセンブリ言語で書いたコードが正しくscanf()を呼べたかどうかも、やはり同じように結果を確認する必要があります。キーボードでタイプできた、というだけでは正しく動作できたことを意味しません。
30
+ 結果を表示させて確認する、そのためにC言語ではprintf()から学び始めますね。アセンブリ言語の動作確認をするにも、まずはアセンブリコードで表示して確認する手段を手にいれることが大事です。それには
31
+ - printf() にパラメータを渡して表示させる手段
32
+ - Cで自分が書いた表示関数に、手際よく必要なデータを渡す手段
33
+
34
+ などを、まずは調査することをお勧めしたいと思います。

1

スタック内のローカル変数領域の使い方を修正

2019/10/23 22:19

投稿

rubato6809
rubato6809

スコア1382

answer CHANGED
@@ -3,12 +3,16 @@
3
3
  subl $32, %esp
4
4
  call ___main
5
5
  leal 22(%esp), %eax
6
- movl %eax, 4(%esp)
6
+ movl %eax, 4(%esp) # オフセット4に sample 配列の先頭アドレス
7
+ movl $LC0, (%esp) # スタックトップ(オフセット0)に "%s"
8
+ call _scanf # scanf("%s", sample);
7
9
 
8
10
  ```
9
11
 
10
- subl $32, %esp した直後から、スタックトップから32バイトは、この関数が自由に使えるローカル変数領域です。32 = 22 + 10 ですから、
12
+ subl $32, %esp した直後から、スタックトップから32バイトは、この関数が自由に使えるローカル変数領域です。32 = 4 + 4 + 14 + 10 ですから、回答を修正しますとスタックトップから
13
+ - 4バイト: "%s" 文字列のアドレス、scanf() の第一引数
14
+ - 4バイト: 配列 sample のアドレス、scanf() の第二引数
11
- - 22バイト: 今のところ何にも使わない領域
15
+ - 14バイト: 今のところ何にも使われていない領域
12
16
  - 10バイト: char sample[10] 用の領域
13
17
 
14
18
  と割り当てています。これがわかれば leal 22(%esp), %eax が sample 配列の先頭アドレスを求めているとわかります。