Я углубился в 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)); line, то самый правый байт правильный, но в некоторых из них все еще есть ведущие единицы.
У кого-нибудь есть объяснение, почему
A) использование memset для очистки моего массива приводит к неправильному (редактировать: неточному) представлению функции и
РЕШЕНИЕ: из-за использования memset (data, 0, sizeof (data)), а не memset (data, 0, 20 * sizeof (unsigned char)). Память не была полностью установлена, потому что она смотрела только на размер указателя, а не на размер всего массива.
Б) что это за байт хранится как в памяти? целые? char? Я не совсем понимаю, что здесь происходит. (пояснение: какой тип указателя я бы использовал для просмотра таких данных в памяти?)
РЕШЕНИЕ: Я тупой. Я забыл ключевое слово unsigned, и вот откуда вся проблема :(
Любая помощь будет принята с благодарностью - я ничего не нашел, когда искал это.
Нил
PS: Я сразу же подумал, что это результат того, что x86 имеет инструкции, которые не заканчиваются байтовой или полубайтовой границей. Но это не имеет большого смысла и не должно вызывать никаких проблем.
Спасибо Уиллу за указание на мою ошибку с типом char. Это должен был быть беззнаковый символ. Однако мне все еще любопытно, как получить доступ к отдельным байтам.