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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

Q&A

解決済

1回答

2623閲覧

gdbのアドレスの結果が一致していない

strike1217

総合スコア651

C

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

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

0グッド

0クリップ

投稿2017/12/17 07:39

#include<stdio.h> #include<string.h> int main(){ char str[] = "you will make me happy\n"; printf("%s", str); for(int i = 0; i < strlen(str) - 1; i++){ printf("str[%d] : %c : %p\n", i, str[i], &str[i]); } return 0; }

結果を一部載せます。

str[0] : y : 0x7fffffffd530 str[1] : o : 0x7fffffffd531 str[2] : u : 0x7fffffffd532 str[3] : : 0x7fffffffd533 str[4] : w : 0x7fffffffd534 str[5] : i : 0x7fffffffd535 str[6] : l : 0x7fffffffd536

次にgdbでスタック領域を覗いてみます。

(gdb) x/30x $rsp
0x7fffffffd4f0: 0x20756f79 0x6c6c6977 0x6b616d20 0x656d2065

これは・・・最初の 'y' 0x79 が0x7ffffffffd4f3の位置にあるようですが・・・
0x7fffffffd5300x7ffffffffd4f3とかなり差があります。
おまけに、0x7ffffffffd4f0 の小さいアドレスの方に、スペース 0x20 が入っていますよね??

どういうことでしょうか?gdbの結果がよくわかりません。
これ、gdbは内部のメモリのリトルエンディアンを自動で元に戻して表示しているんでしょうか??

わかる方いますか??
ALSRは無効にしています。
Linux 64bit debain GCC です。

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

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

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

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

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

guest

回答1

0

ベストアンサー

>これ、gdbは内部のメモリのリトルエンディアンを自動で元に戻して表示しているんでしょうか??
「4バイト整数としてreadした値を16進数で表示」の結果ですね。
リトルエンディアンでintが4バイトの場合は、C言語で

printf("*(int*) %x\n", *((int*)str));``` でも20756f79になるでしょう。 gdbでは、 (gdb) x/8bx (アドレス) と (gdb) x/2wx (アドレス) のような形式で見比べたら良いと思います。 >0x7fffffffd530と0x7ffffffffd4f3とかなり差があります。 ('y'の位置は0x7ffffffffd4f3ではなく0x7ffffffffd4f0ですが、それは別として)最初の実行結果はgdbからではなく直接実行、だとすれば特におかしい結果ではないと思います。実行環境が異なるので。 gdbから実行して、printfの結果が出てからmain関数終了までの間にxコマンドで確認すれば一致しているはずです。

投稿2017/12/17 11:29

okrt

総合スコア366

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

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

strike1217

2017/12/17 11:31

GDBで実行と直接実行するのでは、結果が違う・・・ということですか??
strike1217

2017/12/17 11:35

GDBでは、メモリやレジスタ内部をそのまま表示している・・・と考えてよいんでしょうか?
okrt

2017/12/17 12:45

gdbが内部で具体的にどういうことをやっているか、シェルからの直接実行との環境の違いを語れるような知識は持ち合わせていません。 が、「実行方法が違えば、全く同じ環境というわけではないだろうなあ」という想像はできます。 gdbから実行している最中の情報としては正しいけど、違う方法で実行した場合とはアドレスまで一致することを期待するべきではないのではないでしょうか。 実行方法による差異を減らす1つの方法。 gdbでattachコマンドを使うと、既に実行中のプロセスの情報を見ることが可能です。 ただし、この質問のプログラムそのままでは実行してすぐに終了してしまうので、そうならないような加工が必要です。
strike1217

2017/12/17 12:47

なるほど! ありがとうございます。
strike1217

2017/12/17 13:15

すいません。アセンブリ言語のmov命令って転送する際に「リトルエンディアンに変換して転送」するのでしょうか? それともそのままで転送するんですか?
okrt

2017/12/17 13:43

リトルエンディアンのCPUの場合は、1バイトごとに区切ったアドレスの小さいほうが下位バイト、大きいほうが上位バイトになるでしょうね。 「変換」ではなく、それがリトルエンディアンのCPUにとっての「平常運転」です。 リトルエンディアンで書かれたデータを人間が読もうとすると、「変換」に思えるかもしれません。
strike1217

2017/12/17 14:02 編集

例えば、movabs $0x6c6c697720756f79,%rax となっていたとき、%raxの中は、0x796f752077696c6c とリトルエンディアンになるのでしょうか?
okrt

2017/12/17 14:09

それは0x79(途中省略)6cではなく、0x6c6c697720756f79になっているはず……
strike1217

2017/12/17 14:11

そうですよね!! ほっ・・・ わかりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問