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

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

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

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

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

6回答

4402閲覧

アセンブリでハードコーディングされた情報はどこにあるのか

退会済みユーザー

退会済みユーザー

総合スコア0

アセンブリ言語

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

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

3グッド

2クリップ

投稿2016/05/01 07:19

最近すこしアセンブリをかじり始めた者です。

以下のプログラムを、"objdump -d"で逆アセンブルしたものを見ていたのですが、ハードコーディングした文字列や数値がどこにも書いておらず疑問に思いました。

#include<stdio.h> int main(){ char str[] = "HelloWorld"; int num = 4; printf("%s\n%d\n",str,num); return 0; }

この場合、"HelloWorld"という文字列や4という数値がアセンブリのどこかにかいていそうなものですが見当たりませんでした。

ハードコーディングした情報はどこに保存されているのでしょうか。

raccy, ikuwow, yohhoy👍を押しています

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

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

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

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

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

guest

回答6

0

ベストアンサー

こんにちは。

私もそのコードなら"HelloWorld"がオブジェクト内のどこかにこのままの形で入っていると思っていたのですが、a.exeを直接バイナリーエディタでみても入ってなかったです。

objdump -dを見ると、char str[] = "HelloWorld";は、__do_global_ctors()という関数でコンストラクトされるようです。
gcc 4.9.2のソースをgrepしたところ、この関数の中身は、下記でした。

gcc\gcc-4.9.2\libgcc\config\arc\initfini.c

C

1static void 2__do_global_ctors (void) 3{ 4 func_ptr *p; 5 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 6 (*p) (); 7}

正直、内容はよく分かりませんが、どうも1文字1文字、コンストラクタを呼び出して設定しているようです。これに適合するような初期化バイナリーは少なくともHelloWorldが単純に並んだようなバイト列ではないということと思います。

試しに、下記コードをMinGWでビルドして、a.exeをバイナリーエディタで確認したところ、"HelloWorld "は入っていました。

C

1#include<stdio.h> 2 3int main(){ 4 char const* str = "HelloWorld"; 5 6 printf("%s\n\n",str); 7 8 return 0; 9}

ただし、objdump -d結果には出てきませんでしたので、定数領域は逆アセンブル出力してくれないようです。

しかし、逆アセンブラはオブジェクトからアセンブラ・コードを生成するので、元のソースに較べて失われている情報が多いです。
学習目的なら、otnさんの回答のようにコンパイラにアセンブラ・コードを出力させた方が残っている情報が多いので、より分かりやすいと思います。

投稿2016/05/01 10:27

Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2016/05/01 13:05

皆さまご回答ありがとうございました。なんとなくですが納得しました。 ソース内に書かれた定数情報を調べるなら-sオプションで地道に調べるしかなさそうですね。アセンブリ内で変数として格納されているものとばかり思っていましたが予想以上に奥が深い...。
yohhoy

2016/05/02 06:55 編集

気になって調べてみたところ、最近のCコンパイラでは一定条件をみたす文字列定数を、コード領域(.text section)に直接を埋め込んでしまうようです。これにより、バイナリエディタで実行可能ファイルを覗いても文字列が見当たらない or バラバラに配置されているように見えるようですね。例えばGCC 6.1/x86_64/-O0オプションでは、"HelloWorld"の部分が movabsq $8245905578810697032, %rax と movw $25708, -8(%rbp) のように分解されていました。 素直なコンパイラなら読取専用データ領域(.rodata section)に配置するはずですが、別メモリアドレスからのロード命令を避けるために、命令列に直値として埋め込んで最適化するようです。
退会済みユーザー

退会済みユーザー

2016/05/02 12:47

yohhoyさんありがとうございます。定数の扱いはコンパイル時に一定ではないのですね。
guest

0

文字列定数は、プログラムとは別な領域に書かれています。

数値定数については、最適化で消えることもあります。たとえば、レジスタに0を格納する場合、直接0を代入せずにXOR EAX, EAXと同じレジスタ同士のXORでクリアするほうがx86では命令長・速度ともに有利となります。

セクションとか.textとか ※Linux ELFについて

投稿2016/05/01 08:28

maisumakun

総合スコア145183

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

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

0

objdump -s a.out
で見て下さい。
私の環境では .text の
4005b0 45f831c0 48b84865 6c6c6f57 6f724889 E.1.H.HelloWorH.
4005c0 45e066c7 45e86c64 c645ea00 c745dc04 E.f.E.ld.E...E..
にありました。因みに
400690 01000200 25730a25 640a00 ....%s.%d..
が printf() の書式文字列だと思います。
”HelloWor"と”ld"が分かれている理由は不明です。
(4byte長でダンプしているから、分かれているように見えるだけ?)
当然コンパイラやOSが違えば、文字列を保持する場所は違います。

投稿2016/05/01 12:00

編集2016/05/01 12:05
nob.

総合スコア711

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

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

0

gccを使っているなら、gcc -S ~.cでコンパイルのみとなり、アセンブラソースが拡張子sで出力されますので、それを見ると色々分かるかと思います。

投稿2016/05/01 09:16

otn

総合スコア84499

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

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

0

環境がわからないので外してるかもですが・・
stringsコマンドはどうでしょう?
あるなしぐらいなら確認できると思います。
STRINGS(1)
(今環境がないので確認していません)

投稿2016/05/01 14:03

cateye

総合スコア6851

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

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

退会済みユーザー

退会済みユーザー

2016/05/02 12:45

stringsコマンドも有用ですね。アセンブリのどのセクションに属しているかが分からないため、第一分析として使っています。
guest

0

よくわかりませんが、このへんが参考になるかも
http://qiita.com/usagi/items/a0889903e09c1af2b462

紹介したページでは
objdump でシンボルの位置を探ったのち
od で確認してます。

投稿2016/05/01 08:34

takasima20

総合スコア7458

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問