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

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

ただいまの
回答率

89.04%

アセンブリにて、eaxに0を代入する意味

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,408

jaguarundi

score 19

前提・実現したいこと

アセンブリ言語を勉強しています。
後述のとおり、簡単なC言語のソースをコンパイルし、逆アセンブルしたものを読み解いているのですが、いくつか質問があります。

該当のソースコード

int main(){
    int i;
    i = 1;

    return 0;
}


これをコンパイルし、逆アセンブルしたものがこちらです。

simple:     file format mach-o-x86-64


Disassembly of section .text:

0000000100000f9e <_main>:
   100000f9e:    55                       push   rbp
   100000f9f:    48 89 e5                 mov    rbp,rsp
   100000fa2:    c7 45 fc 01 00 00 00     mov    DWORD PTR [rbp-0x4],0x1
   100000fa9:    b8 00 00 00 00           mov    eax,0x0
   100000fae:    5d                       pop    rbp
   100000faf:    c3                       ret    

Q1. 逆アセンブルしたソースに出現する" mov    eax,0x0"の意味

それまではrbpやrspしかレジスタが登場していないにも関わらず、突如eaxを0に代入する部分の意味があまりよく分かりませんでした。
Cのソースで0が登場しているのは"return 0"の部分ですが、eaxに関連があるのか分かりませんでした。

Q2. DWORD PTR[rbp-0x4]について(※勘違いでした)

(元の質問)初歩的な質問になりますが、push rbs, mov rbs, rspが終わった後に出現するDWORD PTR[rbp-x](xは任意の数)は、スタックフレームを確保するためにxバイトだけメモリを確保する(スタックを下位アドレスにむけて伸ばす)と解釈してよろしいのでしょうか。
(自己解決)
DWORD PTR[rbs-x]は、rbsのアドレスからxバイト、下位アドレスの方に向かったところにあるメモリのアドレスに値を入れる、ということでした。
私の質問内容を実現しているのは、
mov rbp, rsp
sub rsp, 0x10
のようにrspを操作してスタックフレームを確保する技術のようです。

独学なので、初歩的な質問ですが、よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+6

mov    DWORD PTR [rbp-0x4],0x1

スタックをint分開けて、そこをローカル変数(i)のために使ってるってことですね

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+1

1. 逆アセンブルしたソースに出現する" mov    eax,0x0"の意味

おそらく、return 0;の表現だと思われます。環境によって呼出規約が違ってきますが、x64の場合だと、返り値をrax(下半分がeax)に入れる例が多いです。

2. DWORD PTR[rbp-0x4]について
(中略)スタックフレームを確保するためにxバイトだけメモリを確保する(スタックを下位アドレスにむけて伸ばす)と解釈してよろしいのでしょうか。

いえ、これはi = 1;の意味合いです。DWORD PTR [rbp-0x4]で指定されたメモリの箇所に1を入れています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/05 19:41

    > xor eax, eax
    8bit の頃の習慣じゃないですか?
    正確には覚えてないけど、mov より、xor の方が速く、語長も短かった。

    キャンセル

  • 2019/02/05 19:46

    https://reverseengineering.stackexchange.com/questions/14609/xor-eax-eax-in-x64

    x64なのにあえて「xor eax, eax」でクリアする(eaxを使うとraxの上位32ビットは0で埋まる)、なんてテクニックすらあるようです。

    キャンセル

  • 2019/02/05 20:23

    たまに見かけるxor eax, eaxもそういう目的で使われていたのですね、勉強になります(・ω・;)

    キャンセル

+1

  1. 標準的な呼び出し規約ではeaxraxを用いて関数の戻り値を受け渡しします
  2. 伸ばすというよりは用意した(された)領域をiとしてi = 1を実行しています
    さらに言うならば上位アドレスへ伸びてますね
    よく考えたら上位下位ってどっちがどっちだか決まってない気がしてきましたorz

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/05 15:23

    スタックは常にヒープセグメントやテキストセグメントがある方向に伸びる訳ではないのでしょうか?

    私の認識では
    ・スタックセグメントはメモリの高位アドレスに位置し、下位アドレスの方へ伸びていく
    という認識なのですが・・・
    (頭がこんがらがってきました(・ω・;))

    キャンセル

  • 2019/02/05 16:05

    すいません、よく考えるとどっちがどっちだか論拠が見つけられませんでした。

    キャンセル

  • 2019/02/05 20:23

    いえいえ、私の書き方が悪かったです(・ω・;)
    回答ありがとうございました!

    キャンセル

0

アセンブリ言語は、CPUが直接実行できるプログラム(機械語)に変換される事を前提に設計されています。
CPUに含まれるレジスタは、CPUのハードウェアに依存していますから、CPUの種類が違うと対応するアッセンブリ言語も違ってきます。そのためMIPS用とか、X86用とかいうように対応するCPUの種類名が付いているのが普通です。

質問の逆アセンブリ結果の1行目に"simple:     file format mach-o-x86-64"と書かれていますから、このアセンブラは64bit版のX86アーキテクチャのCPU(例えば、インテルのiシリーズ等)用であることが分ります。
X86アーキテクチャのレジスタ構成は、X86アセンブラ/x86アーキテクチャなど、説明しているページがいろいろあります。

「それまではrbpやrspしかレジスタが登場していないにも関わらず、突如eaxを0に代入する部分の意味があまりよく分かりませんでした。」
EAXレジスタはハードウェアとして、X86アーキテクチャのCPUの全てに備わっているものです。アセンブリのコードで定義することで作られる訳ではありません(プログラムを変えたからといって、ICの内部が書き換わったりしないですよね?)。
X86用アセンブリ言語でプログラムを書く際には、基礎知識としてX86アーキテクチャのレジスタ構成などが求められます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る