我正在编写一个程序,如果我在Suse 10 32位系统上编译而不添加-m32选项并在Suse 10 64位上执行它,它可以正常工作。 在这种情况下,我不需要添加-m32选项吗? 我们是否可以直接在64位系统上执行基于32位系统的程序而没有任何副作用? 或者是否需要更新或更改?
GCC工具链默认使用AT&T汇编语法,但可通过.intel_syntax指令获得对Intel语法的支持。 此外,AT&T和Intel语法都有prefix和noprefix版本,不同之处在于它们是否需要使用% sigil为寄存器名称添加前缀。 根据存在的指令,地址常量的格式会发生变化。 我们考虑以下C代码 *(int *)0xdeadbeef = 0x1234; 使用objdump -d ,我们发现它被编译为以下汇编程序指令 movl $0x1234,0xdeadbeef 由于没有涉及寄存器,这是.att_syntax prefix和.att_syntax noprefix的正确语法,即。 嵌入在C代码中,它们看起来像这样 __asm__(“.att_syntax prefix”); __asm__(“movl $0x1234,0xdeadbeef”); __asm__(“.att_syntax noprefix”); __asm__(“movl $0x1234,0xdeadbeef”); 您可以选择用括号括起地址常量,即。 __asm__(“movl $0x1234,(0xdeadbeef)”); 也会奏效。 将sigil添加到普通地址常量时,代码将无法复制 __asm__(“movl $0x1234,$0xdeadbeef”); // won’t compile 当用paranthesis围绕这个表达式时,编译器会在没有警告的情况下发出错误的代码,即 __asm__(“movl $0x1234,($0xdeadbeef)”); // doesn’t warn, but doesn’t work! 这将错误地发出指令 movl $0x1234,0x0 在Intel模式下,如果可能存在歧义,则地址常量必须以段寄存器为前缀,并且必须以操作数大小和PTR标志为前缀。 在我的机器上(采用Windows XP和当前MinGW和Cygwin GCC版本的英特尔双核笔记本电脑),默认情况下使用寄存器ds 。 常量周围的方括号是可选的。 如果省略段寄存器但是括号存在,则也可以正确识别地址常量。 […]
在GCC中读取-I开关的精细打印,我很震惊地发现在命令行上使用它会覆盖系统包含。 来自预处理器的文档 “您可以使用-I覆盖系统头文件,替换您自己的版本,因为在标准系统头文件目录之前搜索这些目录。” 他们似乎并不撒谎。 在两个不同的endian.h系统上使用GCC 7,如果我创建一个文件endian.h : #error “This endian.h shouldn’t be included” …然后在同一目录中创建一个main.cpp (或main.c,相同的区别): #include int main() {} 然后使用g++ main.cpp -I. -o main编译g++ main.cpp -I. -o main g++ main.cpp -I. -o main (或clang,相同的区别)给了我: In file included from /usr/include/x86_64-linux-gnu/sys/types.h:194:0, from /usr/include/stdlib.h:394, from /usr/include/c++/7/cstdlib:75, from /usr/include/c++/7/stdlib.h:36, from main.cpp:1: ./endian.h:1:2: error: #error “This endian.h shouldn’t be included” […]
我正在尝试在Mac OS X Lion上从Erlang( http://www.erlang.org/doc/man/erl_nif.html )编译NIF测试。 我无法编译。 我错过了编译器标志吗? 这是我得到的错误: Computer:~ me $ gcc -fPIC -shared -o niftest.so niftest.c -I /usr/local/Cellar/erlang/R14B02/lib/erlang/usr/include/ Undefined symbols for architecture x86_64: “_enif_make_string”, referenced from: _hello in ccXfh0oG.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status 我也用-m32尝试了这个,但它说没有i386架构。 谢谢!
有没有办法,除了在每个函数原型上放置一个属性,让gcc知道C函数永远不会传播exception,即在extern “C”声明的所有函数都应该是__attribute__((nothrow)) ? 理想的是-f风格的命令行选项。
我正在尝试优化计算密集型算法,并且遇到了一些缓存问题。 我有一个巨大的缓冲区,偶尔写入并随机写入,并在应用程序结束时只读取一次。 显然,写入缓冲区会产生大量的缓存未命中,并且还会污染之后需要再次进行计算的缓存。 我尝试使用非时间移动instrinsics,但缓存未命中(由valgrind报告并由运行时测量支持)仍然会发生。 但是,为了进一步研究非时间动作,我写了一个小测试程序,你可以在下面看到。 顺序访问,大缓冲区,只写。 #include #include #include #include void tim(const char *name, void (*func)()) { struct timespec t1, t2; clock_gettime(CLOCK_REALTIME, &t1); func(); clock_gettime(CLOCK_REALTIME, &t2); printf(“%s : %f s.\n”, name, (t2.tv_sec – t1.tv_sec) + (float) (t2.tv_nsec – t1.tv_nsec) / 1000000000); } const int CACHE_LINE = 64; const int FACTOR = 1024; float *arr; int […]
我正在使用GCC Linaro编译器来编译我的代码。 它从libio.h抛出错误unknown type name size_t 。 它包含在stdio.h 。 在我的代码中,我只包括stdio.h 。 可以请任何人如何解决此错误。
对于OpenMP,当我的代码使用其API中的函数(例如,omp_get_thread_num())而不使用其指令(例如#pragma omp …)时, 为什么直接将libgomp.a指定为gcc而不是使用-fopenmp不起作用,例如 gcc hello.c /usr/lib/gcc/i686-linux-gnu/4.4/libgomp.a -o hello 更新:我刚刚发现链接到libgomp.a不起作用,但链接到libgomp.so工作。 这是否意味着OpenMP不能静态链接? 为什么-fopenmp只能在不指定库文件的情况下工作 gcc hello.c -fopenmp -o hello 更新:换句话说,当使用-fopenmp时,为什么不需要显式链接到libgomp.so? 为什么这也编译: gcc hello.c -L/usr/lib/gcc/i686-linux-gnu/4.4/ -lgomp -o hello 如果有的话,这会忽略代码中的OpenMP指令吗? 感谢致敬!
我正在使用gnu工具链。 我怎样才能在运行时找到函数的调用者? 即例如函数B()被许多函数使用函数指针调用。 现在,每当B被调用时,我想打印调用者名称。 我需要这个来调试某个问题。
我想在不编写内联汇编的情况下读取堆栈指针寄存器值。我想这样做的原因是因为我想将堆栈指针寄存器值分配给数组元素,我发现使用内联汇编访问数组很麻烦。 所以我想做那样的事情。 register “rsp” long rsp_alias; <— How do I achieve something like that in gcc? long current_rsp_value[NUM_OF_THREADS]; current_rsp_value[tid] = rsp_alias; gcc有什么可能吗?