私は Linux と C について深く掘り下げてきましたが、関数がどのようにメモリに格納されるのかに興味があります。私は次の機能を持っています:
void test(){
printf( "test\n" );
}
十分に単純です。この機能を持つ実行可能ファイルで objdump を実行すると、次のようになります。
08048464 <test>:
8048464: 55 push %ebp
8048465: 89 e5 mov %esp,%ebp
8048467: 83 ec 18 sub $0x18,%esp
804846a: b8 20 86 04 08 mov $0x8048620,%eax
804846f: 89 04 24 mov %eax,(%esp)
8048472: e8 11 ff ff ff call 8048388 <printf@plt>
8048477: c9 leave
8048478: c3 ret
これはすべて正しく見えます。興味深いのは、次のコードを実行するときです。
int main( void ) {
char data[20];
int i;
memset( data, 0, sizeof( data ) );
memcpy( data, test, 20 * sizeof( char ) );
for( i = 0; i < 20; ++i ) {
printf( "%x\n", data[i] );
}
return 0;
}
私は以下を取得します(これは正しくありません):
55
ffffff89
ffffffe5
ffffff83
ffffffec
18
ffffffc7
4
24
10
ffffff86
4
8
ffffffe8
22
ffffffff
ffffffff
ffffffff
ffffffc9
ffffffc3
memset( data, 0, sizeof( data ) ); を除外することを選択した場合 行の場合、右端のバイトは正しいですが、先頭の 1 が残っているものもあります。
誰にも理由の説明がありますか
A) memset を使用して配列をクリアすると、関数の表現が正しくなくなります (編集: 不正確)。
解決策: memset( data, 0, 20 * sizeof( unsigned char ) ) ではなく memset( data, 0, sizeof( data ) ) を使用したことが原因でした。配列全体のサイズよりもポインターのサイズのみを調べていたため、メモリが完全に設定されていませんでした。
B) メモリに格納されているこのバイトは何ですか? 整数?チャー?ここで何が起こっているのかよくわかりません。(明確化:メモリ内のそのようなデータをトラバースするためにどのタイプのポインタを使用しますか?)
解決策: 私はばかです。unsigned キーワードを忘れてしまいました。それが問題全体の原因です:(
どんな助けでも大歓迎です-これを探し回っても何も見つかりませんでした。
ニール
PS: これは、x86 の命令がバイト境界またはハーフバイト境界で終わらないことが原因であるとすぐに思いました。しかし、それはあまり意味がなく、問題が発生することはありません。
char 型のエラーを指摘してくれた Will に感謝します。unsigned char である必要があります。ただし、個々のバイトにアクセスする方法についてはまだ興味があります。