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

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

ただいまの
回答率

88.91%

ハンドアセンブラ

解決済

回答 3

投稿 編集

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

strike1217

score 583

objdump -d a.out の <main>セクションの一番最初は、
push %rbp  → 0x55 となっていました。

binutilsのopcodesの中に、ニーモニックとレジストリの値の一覧を探しました。

// ニーモニック
 { "push", 1, 0x50, None, 1,
  { "push", 1, 0xff, 0x6, 1,
  { "push", 1, 0x6a, None, 1,
  { "push", 1, 0x68, None, 1,
  { "push", 1, 0x6, None, 1,
  { "push", 1, 0xfa0, None, 2,
  { "push", 1, 0x50, None, 1,
  { "push", 1, 0xff, 0x6, 1,
  { "push", 1, 0x6a, None, 1,
  { "push", 1, 0x68, None, 1,
  { "push", 1, 0xfa0, None, 2,
  { "pusha", 0, 0x60, None, 1,
  { "pushf", 0, 0x9c, None, 1,
  { "pushf", 0, 0x9c, None, 1,

レジストリに関して、、、

static const char *intel_names64[] = {
  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
};
rbx, Reg64|BaseIndex, 0, 3, Dw2Inval, 3
rsp, Reg64, 0, 4, Dw2Inval, 7
rbp, Reg64|BaseIndex, 0, 5, Dw2Inval, 6
rsi, Reg64|BaseIndex, 0, 6, Dw2Inval, 4
rdi, Reg64|BaseIndex, 0, 7, Dw2Inval, 5
{ "rbp",
    { { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
    0, 5, { Dw2Inval, 6 } },


push命令だけではなく、オペランドをくっつけたときにバイナリコードになりますが・・・

どのような手順で計算すれば、push + %rbp が, 16進数で0x55となるのでしょうか?

やり方を知っている方はぜひ教えてください。

Linux 64bit です。

[追記]

printf("you will make me happy!!\n");


をアセンブルすると、 mov    $0x4005a4,%edi
you will make me happy!! という文字列が逆順に入っているのは、「リトルエンディアンだから」という理由でしょうか?

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+4

Linux 64bit です。 

OSは関係ないです。プロセッサの種類が問題になるので、例えば「AMD64プロセッサ」などというべきでしょう。

どのような手順で計算すれば

こうした疑問を解決するにはプロセッサのデータシートを参照すればよいと思います。言語プロセッサーを書いた人たちはこうしたデータシートを参照してコンパイラー、アセンブラー、逆アセンブラーなどのユーティリティーを書いたはずです。

インターネット上でAMD64プロセッサ(IA32の互換プロセッサ)での命令一覧を探してみると、PUSH reg(汎用レジスタ)はレジスターの種類に応じて0x50~0x57になり、汎用レジスターは%eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %espの8個なんてことが書いてあるので、オペコードのビット列は0101 0rrrであり、rrrは%eax=0,%ebx=1,...となっているであろうことが想像できます。

訂正:上記のレジスターの名前は自分がみたページからコピペしましたが順番がおかしいのと記法が違いますね・・・yohhoyさんがおっしゃるように一次情報を参照すること、記法の違いなどに注意しないといけませんね。失礼しました。

ちなみにAMD64プロセッサのアセンブリー命令の全てを把握するには自然プロセッサの仕様を把握することが必要で、そのためにはプロセッサのハードウェアとしての背景知識が必要になってくるので個人で学ぼうとするのはなかなかに敷居が高いように思えました。そうではなく基本的なデータ転送命令や演算命令、分岐命令程度と汎用レジスターの一覧の程度を把握するだけならそれほど難しくはないです。またそれだけでもそこそこの役には立つとは思います。

you will make me happy!! という文字列が逆順に入っている

メモリー上には別に逆順に入ってません。C言語の素直な実装では'y','o','u',...の順番にメモリー上に配置されますが、単にそれを4バイトずつダンプしたような表現をみたとき逆順になっているかのように見えただけだと思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/09 12:35

    ああ~~
    単純に論理和なのですね!

    全ての「ニーモニック+オペランド」は、論理和を取れば機械語になる!ということで良いのでしょうか?

    キャンセル

  • 2017/05/09 12:42

    それはデータシートに書かれたオペコードの仕様をきちんとみて判断してください。必ずしもそうならない場合もあるかも知れませんし。同じpushでも0x50-0x57でないものもありますよ?
    一般的にはプロセッサの設計者が機械語をどのように設計するかに依存して様々に変わります。それはプロセッサの設計に深くかかわってます。汎用レジスターはプロセッサの中では番号によって識別する設計が一般的でしょうからレジスター番号を基本のオペコードの特定のビット位置に置くという設計はよくあるとは思います。

    キャンセル

  • 2017/05/09 12:46

    わかりました。
    結構面倒なのですね!

    キャンセル

+4

どのような手順で計算すれば、push + %rbp が, 16進数で0x55となるのでしょうか?

可能な限り、一次情報源をあたってください。Intel社より "Intel® 64 and IA-32 Architectures Software Developer Manuals" が公開されています。"Intel® 64 and IA-32 architectures software developer’s manual combined volumes: 1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4" が全部入りドキュメントです。

"Volume 2: Instruction Set Reference, A-Z" の PUSH—Push Word, Doubleword or Quadword Onto the Stack より:

 Opcode      Instruction  
 50+rd   PUSH r64 

表中 "+rd" は 3.1.1.1 Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix), Table 3-1. Register Codes Associated With +rb, +rw, +rd, +ro より RBP == 5 と定義されています。

以上より、PUSH RBP のオペコード(16進数)は 50+5 つまり 55 となります。

補足:Intel社マニュアルは「Intel記法」で記載されていますが、GNU系ツールでは「AT&T記法」とよばれる表現方法を採用します。この回答の範囲では、レジスタ名称RBP(Intel記法)/%rbp(AT&T記法)の読み替えが必要です。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/09 14:00

    アーキテクチャのよって異なるのですね!

    ニーモニックとオペランドの情報から機械語を算出するには、CPUによりけりということですね・・・

    キャンセル

  • 2017/05/09 14:10 編集

    Intelプロセッサは下方互換性を最重要視しているため、複雑怪奇な機械語命令体系になっています。おかげでマーケット的には成功していますが、学習(?)向けにはもっとシンプルな命令体系のプロセッサの方が良いかもしれません...

    またアセンブラを学ぶという話と、機械語命令について学ぶ話はレイヤが異なると思います。後者に興味があるならば書籍「コンピュータの構成と設計」シリーズをお勧めしておきます。著者名から"パタヘネ本"と呼ばれたりします。

    キャンセル

  • 2017/05/09 14:14

    複雑怪奇な機械語命令体系
    そ、そうなんですか!

    Intel CPU であれば、互換性を保つために、機械語の算出は1通りのやり方で行える可能性もあるんですかね・・・

    キャンセル

0

KSwordOfHasteさんの補足のようになりますが、

まずは386DXのデータシート。
http://pdf.datasheetcatalog.com/datasheet/Intel/mXtuvqv.pdf

p.96より、

PUSH
 Register (short form) 0 1 0 1 0 reg

レジスタに関してはp.112より、

000 EAX
001 ECX
010 EDX
011 EBX
100 ESP
101 EBP
110 ESI
111 EDI

よって、push ebpは、

0 1 0 1 0 1 0 1 = $55

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/09 12:58

    0 1 0 1 0 1 0 1 = $55
    これ単純に論理和ですね!
    論理和にならない場合もあるんですか?

    キャンセル

  • 2017/05/09 13:14

    インストラクションセットを見た上で質問しているのでしょうか?
    質問の意図も不明です。

    キャンセル

  • 2017/05/09 13:31

    すいません。論理和ではありません。

    0 1 0 1 0 + 101 → 01010101
    ニーモニックとオペランドから機械語を作り出す時は、全て、この方法でできるんですか?

    キャンセル

  • 2017/05/09 13:48

    出来たらどうで、出来なかったらどうなんでしょうか?
    何のために質問しているのでしょうか?

    キャンセル

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

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

関連した質問

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