我正在尝试使用内联汇编创建一个ldm ( stm )指令,但是在表达操作数方面存在问题(特别是:它们的顺序)。 一件微不足道的事 void *ptr; unsigned int a; unsigned int b; __asm__(“ldm %0!,{%1,%2}” : “+&r”(ptr), “=r”(a), “=r”(b)); 不起作用,因为它可能会将r1和b放入r0 : ldm ip!, {r1, r0} ldm期望寄存器按升序排列(因为它们ldm编码)所以我需要一种方法来说明用于a的寄存器低于b的寄存器。 一个简单的方法是固定分配寄存器: register unsigned int a asm(“r0”); register unsigned int b asm(“r1”); __asm__(“ldm %0!,{%1,%2}” : “+&r”(ptr), “=r”(a), “=r”(b)); 但这会消除很多灵活性,并可能使生成的代码不是最佳的。 gcc(4.8)是否支持ldm/stm特殊约束? 或者,有更好的方法来解决这个问题(例如一些__builtin函数)? 编辑: 因为有建议使用“更高级别”的结构……我想解决的问题是32位32位字的打包(例如输入是8个字,输出是5个字)。 伪代码是 asm(“ldm %[in]!,{ %[a],%[b],%[c],%[d] }” …) asm(“ldm […]
我们使用RPM文件在AIX 6.1上安装了GCC和libgcc 。 我想知道为什么“libgcc_s.a”没有在以下文件夹下创建? /opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/ 该文件夹中有一个libgcc.a但libgcc_s.a没有libgcc.a ,链接器似乎想要那个libgcc_s.a文件 我问的原因是,如果我尝试在AIX 6.1上创建一个简单的“hello world”类型的共享库,它会抱怨并说”cannot find libgcc_s.a”像”cannot find libgcc_s.a” 。 我运行了一个命令: find / -name ‘*libgcc*’ -print 2>/dev/null 尝试在tha机器上找到libgcc_s.a,但没有任何东西;-( 知道如何将libgcc_s.a到AIX机器上吗?
一般来说,根据C标准,保证带有0的memset()会将C结构中的填充位清零吗? 那gcc怎么样? 例如,类似于: struct MyStruct { unsigned char member1; unsigned int member2; char member3; unsigned char member4; float member5; }; struct MyStruct ms; memset(&ms, 0, sizeof( struct MyStruct));
我有以下C程序: int main() { int c[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2}; return c[0]; } 当使用带-gcc的-S指令编译时,我得到以下程序集: .file “array.c” .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $0, -48(%rbp) movl $0, -44(%rbp) movl $0, -40(%rbp) movl $0, […]
GCC手册仅显示了__builtin_expect()放置在’if’语句的整个条件周围的示例。 我还注意到GCC不会抱怨如果我使用它,例如,使用三元运算符,或任何任意积分表达式,即使是未在分支上下文中使用的表达式。 所以,我想知道其实际使用的基本限制是什么。 当它在这样的三元运算中使用时是否会保持其效果: int foo(int i) { return __builtin_expect(i == 7, 1) ? 100 : 200; } 那么这个案子呢: int foo(int i) { return __builtin_expect(i, 7) == 7 ? 100 : 200; } 还有这个: int foo(int i) { int j = __builtin_expect(i, 7); return j == 7 ? 100 : 200; }
const声明有助于编译器(GCC)生成更快的代码,还是只对可读性和正确性有用? Zed Shaw认为const在C / C ++中没用或过度使用: 接下来是对const的所有奇怪的魅力。 由于一些奇怪的原因,C ++喜欢让你在声明的每个部分都使用const,但是我得到与C相同的最终结果:调用一个函数。 (……) (来自: http : //librelist.com/browser//mongrel2/2010/7/15/c-verses-c++/#770d94bcfc6ddf1d8510199996b607dd )
我正在编写代码暂时使用我自己的堆栈进行实验。 当我使用文字内联汇编时,这很有效。 我将变量位置硬编码为ebp的偏移量。 但是,我希望我的代码可以在不使用硬编码内存地址的情况下工作,所以我一直在研究GCC的扩展内联汇编。 我所拥有的是以下内容: volatile intptr_t new_stack_ptr = (intptr_t) MY_STACK_POINTER; volatile intptr_t old_stack_ptr = 0; asm __volatile__(“movl %%esp, %0\n\t” “movl %1, %%esp” : “=r”(old_stack_ptr) /* output */ : “r”(new_stack_ptr) /* input */ ); 这一点是首先将堆栈指针保存到变量old_stack_ptr中。 接下来,堆栈指针(%esp)将被我在new_stack_ptr中保存的地址覆盖。 尽管如此,我发现GCC将%esp保存到old_stack_ptr中,但是没有用new_stack_ptr替换%esp。 经过深入检查,我发现它实际上扩展了我的程序集并添加了它自己的指令,如下所示: mov -0x14(%ebp),%eax mov %esp,%eax mov %eax,%esp mov %eax,-0x18(%ebp) 我认为GCC正试图保留%esp,因为我没有将它明确声明为“输出”操作数……我可能完全错了… 我真的很想使用扩展的内联汇编来实现这一点,因为如果没有,似乎我必须将%ebp的位置偏移“硬编码”到程序集中,我宁愿使用像这样的变量名。特别是因为这段代码需要在几个不同的系统上运行,这些系统似乎都以不同的方式抵消了我的变量,因此使用扩展的内联汇编可以让我明确地说出变量位置……但是我不明白它为什么会这样做额外的东西,不要让我像以前一样覆盖堆栈指针,自从我开始使用扩展程序集以来,它一直在这样做。 我感谢任何帮助!
很多时候我想要一个函数来接收可变数量的参数,例如以NULL结尾 #define push(stack_t stack, …) _push(__VARARG__, NULL); func _push(stack_t stack, char *s, …) { va_list args; va_start(args, s); while (s = va_arg(args, char*)) push_single(stack, s); } 如果foo收到非char*变量,我可以指示gcc或clang警告吗? 类似于__attribute__(format) ,但是对于同一指针类型的多个参数。
gcc提供可能/不太可能的提示 ,帮助编译器生成具有更好分支预测的机器代码。 有没有关于如何正确使用或不使用这些提示影响某些真实系统上实际代码性能的数据?
我有以下C代码: #include int main(int argc, char ** argv) { double mydouble = 100.0; double whatever = round(mydouble); return (int) whatever; } 当我编译它时,我收到警告: round_test.c: In function ‘main’: round_test.c:6: warning: implicit declaration of function ’round’ round_test.c:6: warning: incompatible implicit declaration of built-in function ’round’ 我对C生锈了,但我认为#include将round()的声明带入了范围。 我检查了我的ANSI标准(C99是我唯一的副本),它确认了math.h标头中存在round()函数。 我在这里想念的是什么? 编辑:编译器是Ubuntu上的GCC 4.3.2(intrepid,IIRC)。 运行gcc -E给出: $ gcc -E round_test.c | grep […]