Nei*_*eil 9 c linux memory function objdump
我一直在深入研究Linux和C,我很好奇函数是如何存储在内存中的.我有以下功能:
void test(){
printf( "test\n" );
}
Run Code Online (Sandbox Code Playgroud)
很简单.当我在具有此功能的可执行文件上运行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
Run Code Online (Sandbox Code Playgroud)
一切看起来都正确.有趣的是,当我运行以下代码时:
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;
}
Run Code Online (Sandbox Code Playgroud)
我得到以下(这是不正确的):
55
ffffff89
ffffffe5
ffffff83
ffffffec
18
ffffffc7
4
24
10
ffffff86
4
8
ffffffe8
22
ffffffff
ffffffff
ffffffff
ffffffc9
ffffffc3
Run Code Online (Sandbox Code Playgroud)
如果我选择省略memset(数据,0,sizeof(数据)); 行,然后最右边的字节是正确的,但其中一些仍然有前导1.
有没有人对原因有任何解释
A)使用memset清除我的数组会导致函数的错误(编辑:不准确)表示,以及
解决方案:是由于使用了memset(数据,0,sizeof(数据)),而不是memset(数据,0,20*sizeof(unsigned char)).内存未完全设置,因为它只查看指针大小而不是整个数组的大小.
B)这个字节存储在内存中是什么?整型?炭?我不太明白这里发生了什么.(澄清:我将使用什么类型的指针来遍历内存中的这些数据?)
解决方案:我很蠢.我忘记了unsigned关键字,这就是整个问题的来源:(
任何帮助将不胜感激 - 我在寻找这个时找不到任何东西.
尼尔
PS:我的直接想法是,这是x86具有不以字节或半字节边界结束的指令的结果.但这并没有多大意义,也不应该造成任何问题.
感谢Will用char类型指出我的错误.它应该是unsigned char.我仍然对如何访问单个字节感到好奇.
这是您尝试执行的代码的一个更简单的情况:
int main( void ) {
unsigned char *data = (unsigned char *)test;
int i;
for( i = 0; i < 20; ++i ) {
printf( "%02x\n", data[i] );
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我所做的更改是删除多余的缓冲区,而不是使用指向 的指针test
,使用unsigned char
代替char
,并将 更改printf
为 use %02x
,以便它始终打印两个字符(它不会修复出现的“负”数ffffff89
) - 这是通过unsigned
数据指针修复的)。
x86 中的所有指令都以字节边界结束,编译器通常会插入额外的“填充指令”以确保分支目标与 4、8 或 16 字节边界对齐以提高效率。