Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 强制优化器不对字符数组的内容进行任何假设_C_Gcc - Fatal编程技术网

C 强制优化器不对字符数组的内容进行任何假设

C 强制优化器不对字符数组的内容进行任何假设,c,gcc,C,Gcc,我如何才能强制gcc的优化器不对代码中的字符数组的内容进行任何假设?据我所知,这应该可以用volatile关键字实现,但它似乎不起作用 请看下面的代码: #include <stdio.h> int main(int argc, char *argv[]) { volatile unsigned char magickey[] = "\xDE\xAD\xC0\xDE\xC0\xDE\xCA\xFE\xC0\xCA\xC0\x1A"; volatile un

我如何才能强制gcc的优化器不对代码中的字符数组的内容进行任何假设?据我所知,这应该可以用
volatile
关键字实现,但它似乎不起作用

请看下面的代码:

#include <stdio.h>

int main(int argc, char *argv[])
{
    volatile unsigned char magickey[] =  "\xDE\xAD\xC0\xDE\xC0\xDE\xCA\xFE\xC0\xCA\xC0\x1A";    
    volatile unsigned int val;

    //  printf("TEST: %p\n", magickey); 

    val = (magickey[0] << 24) | (magickey[1] << 16) | (magickey[2] << 8) | magickey[3];

    printf("TEST2: %x\n", val);

    return 0;
}
我希望能够在十六进制编辑器中打开可执行文件,并更改
magickey
char数组的前4个字节,
val
应包含通过修改可执行文件将其十六进制设置到char数组中的字节

只有在第一次调用
printf
被停用时(如上所示的代码中),此功能才起作用。但是,只要我激活对
printf
的第一个调用,无论我使用十六进制编辑器将哪些值写入可执行文件,程序都会打印
TEST2:deadc0de

这让我很困惑。对
printf
的第一次调用似乎完全无害,因为它只打印字符数组的地址。我不明白为什么激活这一行会以任何方式影响优化器


所以我一定是做错了什么。我该怎么做才能强制优化器不对
magickey
char数组的内容进行任何假设,这样我就可以在编译后通过使用十六进制编辑器对可执行文件进行黑客攻击来填充它,并且我使用十六进制编辑器写入其中的字节被正确复制到
val
volatile
似乎并不真正起作用

当您使用
gcc-O3
编译时,它可能被优化到打印语句被硬编码到应用程序后面的print
deadc0de
。查看使用
-O2
-O1
标志进行十六进制编辑是否会得到相同的结果。您是将
magickey
声明为全局变量还是局部变量?当您正在修改二进制文件时,应将问题编辑为包含一个字符串,这样它就不再是有效的编译器生成的文件。所以你不能合法地要求任何东西。你可以想出一个解决方案,这个解决方案在此时此地就可以使用,但你不能保证将来也可以使用。好吧,问题是数组是一个局部变量。因此,gcc知道外部参与者(例如硬件、中断例程、其他线程)无法访问该阵列。因此,修改数组的唯一方法是将数组的地址传递给某个函数,例如
printf
。尝试定义一个空函数
voidfoo(char*unused){}
,将
magickey
传递给该函数,然后查看gcc的功能。或者干脆将
magickey
声明为全局变量(这样理论上硬件、中断和其他线程都可以访问它)。@user3386109:太好了,使用全局变量确实解决了问题。谢谢!
gcc -O3 test.c