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

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

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

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

Q&A

解決済

2回答

2878閲覧

アセンブリ言語の基本 part2

strike1217

総合スコア651

アセンブリ言語

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

0グッド

1クリップ

投稿2017/07/06 12:58

編集2017/07/06 13:02

リンク内容
前回の続きで、基本を!

sub命令についておかしな点があります。
私の持っている本にはこうあります。
subl -8(%rbp), %eax

これはメモリのRBP-8 のアドレスのところにある値から、EAXの値を引いてその結果をEAXにいれます。

ところが、実際にやってみると、どうも逆のようです。

17 movl $1, -4(%rbp) 18 movl $2, -8(%rbp) 19 movl -4(%rbp), %eax 20 subl -8(%rbp), %eax

eaxは -1 が入ります。

(1)同じAT&T構文でも、様々な書き方が存在するんでしょうか?
なにによって書き方が決まるのでしょうか?
使用しているコンパイラ?OS?
私の本が間違っているのでしょうか??

(2)関数の呼び出しの際にRSPをベースポインタからずらす場合がある。
subq $16, %rsp

main()内とかには、よくありますよね・・・
別の関数を呼び出したりする際に、上記のような一行が入っていない場合があります。
この違いはなんでしょうか?
どんな時に、RSPをズラして、どんな時には、ズラさないのでしょうか?

RSPをズラす、ズラさないは何によって決まっているのでしょうか?

(3)無駄なコードが多い理由はなんでしょうか??

17 movl $1, -4(%rbp) 18 movl $2, -8(%rbp) 19 movl -4(%rbp), %eax 20 subl -8(%rbp), %eax 21 movl %eax, -12(%rbp) 22 movl -12(%rbp), %eax 23 movl %eax, %esi 24 leaq .LC0(%rip), %rdi 25 movl $0, %eax 26 call printf@PLT 27 movl $0, %eax 28 leave

21 movl %eax, -12(%rbp)
22 movl -12(%rbp), %eax
23 movl %eax, %esi
この部分は一行に出来ると思います。
movl %eax, %esi

最適化しても、ちょくちょく無駄なコードが入っています。
なぜこのような無駄なコードが入っているのでしょうか?
セキュリティのためですか?人間が無闇にいじくると脆弱性が生まれる危険性はありますかね?

例えば、前回出てきた。
25 movl $0, %eax
これについてもそうですが・・・・
削除しても動作自体に問題はありませんでした。
しかし、削除したらマズイかそれとも大丈夫なのかの判断が出来ません。

ちょっと前回より細かい場所なんのですが、気になってしかたありません。
どなたか教えてください。

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

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

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

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

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

mugicya

2017/07/06 18:06

eax の初期値はなんですか?それと、この二モニックが何向けかわかりませんがオペランドは、どっちがソースでディスティネーションですか?
mugicya

2017/07/06 18:16

無駄なコードが多い理由はなんでしょうか??の所で、元のソース(C?)がないと、無駄なのなどうか、なぜ付いているのかは判別できません。
guest

回答2

0

(1)リンク内容によると
sub src, dst # dst = dst - src
だそうです。AT&T記法を記述した原典は見つかりませんでした

(2)スタック上に空きを作っています。呼び出し前に引数を格納する場合や、戻り値を入れてから関数から戻る場合があります

(3)-12(%rpb)が変数に割り当ててあり、その変数を直後に使う必要があるのでは?

Cコンパイラのオプションに「Cソースとアセンブラソースをマージして出力する」というのがありませんか?
Cとアセンブラを対比してみることが出きるので、理解しやすいと思います。

なにによって書き方が決まるのでしょうか?

簡単に言ってしまえば、アセンブラ処理系の作成者が決めます。
sub a,b を a = a - b とするか、b = b - a とするかは、sub a,b を読み込んでどういうバイナリコードを生成するかの問題で、アセンブラ・プロセッサを作るときにどうにでもできます。

投稿2017/07/07 01:48

nob.

総合スコア711

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

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

strike1217

2017/07/07 01:51

(2)番目については・・・ 呼び出し前というのは、別の関数を呼び出す前ということですよね? 別の関数のための領域という事でよろしいんでしょうか??
strike1217

2017/07/07 01:52

> その変数を直後に使う必要があるのでは? 再利用したりする場合は、確かに必要な行ですよね。
guest

0

ベストアンサー

質問は一つずつにしません?

#1 sub

これはメモリのRBP-8 のアドレスのところにある値から、EAXの値を引いてその結果をEAXにいれます。

これが間違いです。
EAXから「メモリのRBP-8のアドレスのところにある値」を引いて、その結果をEAXに入れます。
sub <op1>,<op2>op2 = op2 - op1ということ。

#2 スタック

呼び出し先に渡す引数の領域では?
やってることはpushと同じかと。

#3 無駄なコード?

21 movl %eax, -12(%rbp) 22 movl -12(%rbp), %eax 23 movl %eax, %esi この部分は一行に出来ると思います。 movl %eax, %esi

三行のコードと一行のコードはイコールではありません。
一行にすると-12(%rbp)に値が入りません。

投稿2017/07/07 00:43

編集2017/07/07 01:03
fuzzball

総合スコア16731

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

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

strike1217

2017/07/07 01:45

> 質問は一つずつにしません? すいません。次回から気を付けます。 sub <op1>,<op2>はop2 = op2 - op1 やはり、本が間違っていましたか! 分かりました。
strike1217

2017/07/07 01:47

(2)については・・・ 別の関数に渡すパラメータが多いときに、スタック経由でパラメータを渡すことが可能ですよね。 別の関数に渡すパラメータを入れておく領域という理解で正しいですか?
fuzzball

2017/07/07 02:08

そうですね。 あと、.nobさんが書かれていますが戻り値の受取用でもありますね。
strike1217

2017/07/07 02:22

movl %eax, -4(%rbp) 例えば、このようにすれば、スタックの中に値を入れることはできます。 subでスタックポインタをズラらさないまま、別の関数を呼び出したら、call命令の段階で、リターンアドレスがpushされると思いますが、-4(%rbp)の領域はリターンアドレスで上書きされるんですか?
fuzzball

2017/07/07 02:38 編集

>>例えば、このようにすれば、スタックの中に値を入れることはできます。 その一行だけ見て「スタックに値を入れている」と思う人はいないと思います。
strike1217

2017/07/07 02:43 編集

movl $6, %eax movl %eax, -4(%rbp) こうなら、大丈夫ですかね? 要は、-4(%rbp)の領域はリターンアドレスで上書きされるため、別の関数から戻ってきた時に 再度-4(%rbp)の領域の値を使用したい場合、その領域を守るために、スタックポインタをズラしているとも考えられるなぁ~~~と思いまして・・・
fuzzball

2017/07/07 02:53

いや、rbpってスタックポインタじゃないですし。
strike1217

2017/07/07 02:55

-4(%rbp)はスタックの領域ですよね?
strike1217

2017/07/07 02:57

-4(%rbp)の領域はリターンアドレスで上書きされるため、別の関数から戻ってきた時に 再度-4(%rbp)の領域の値を使用したい場合、その領域を守るために、「subq $16, %rsp」 をすることによってスタックポインタをズラしているとも考えられるなぁ という事ですが・・・
fuzzball

2017/07/07 02:59

rbpの値が分からないので答えられません。 質問内のコードにも、コメント欄のコードにも、rbpに値を代入するコードは一度も現れていません。
strike1217

2017/07/07 03:04

push %rbp movl %rsp, %rbp あ、あらかじめこうなっていると前提で話しています。
fuzzball

2017/07/07 03:51

「その領域を守るために」というのは考え方が逆です。 その領域を使うからスタックポインタをマイナスしているのです。
strike1217

2017/07/07 03:57

なるほど!! subq $16, %rspしていない状態で、スタック領域にmovl %eax, -4(%rbp)で入れたものは、pushによって上書きされてしまう という理解で正しいわですね!
fuzzball

2017/07/07 04:04 編集

なんでこんな当たり前のことを今になって理解しているのでしょうか? pushやcallの動作を理解していないのでしょうか?
strike1217

2017/07/07 04:08 編集

いえ。自分の理解が間違っている可能性があったので・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問