如何修改C指针?

ysa*_*sap 9 c gcc pointers

在现代处理器中,可以从存储器加载寄存器,然后将索引指针后修改所需的值.例如,在我们的嵌入式处理器中,这将通过以下方式完成:

ldr r0, [r1], +12
Run Code Online (Sandbox Code Playgroud)

这意味着 - 将r1指向的值加载到r0,然后将r1递增12:

r0 = [r1]
r1 = r1 + 12
Run Code Online (Sandbox Code Playgroud)

在C语言中,使用指针算术,可以使用指针分配值,然后将指针前进1:

char i, *p, a[3]={10, 20, 30};

p = &(a[0]);
i = *p++;
// now i==10 and p==&(a[1]).
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种取消引用指针的方法,同时用1以外的偏移量对其进行后期修改.这是否可以在C中进行,因此它可以很好地映射到类似的asm指令?

注意:

i = *p+=2;
Run Code Online (Sandbox Code Playgroud)

增加[0] w/o修改指针的值,并且:

i = *(p+=2);
Run Code Online (Sandbox Code Playgroud)

预修改指针,所以在这种情况下i==30.

Arj*_*kar 7

  1. 是的,这是可能的.

  2. 你不应该做奇怪的指针数学来实现它.

  3. 它不仅是关于优化设置,您的GCC后端需要告诉 GCC它具有这样的功能(即当GCC本身正在编译时).基于这些知识,GCC自动将相关序列组合成单个指令.

即如果你的后端写得正确,甚至是这样的:

 a = *ptr;
 ptr += SOME_CONST;
Run Code Online (Sandbox Code Playgroud)

应该成为一个修改后的指令.

如何在编写后端时正确设置?(请你友好的邻居GCC后端开发人员为你做这件事):

如果您的GCC后端被调用foo:

  1. 在GCC源代码树中,后端描述和挂钩位于gcc/config/foo/.
  2. 在那里的文件(与GCC一起编译)中,通常有一个foo.h包含大量#defines描述机器功能的标题.
  3. GCC期望支持后增量的后端定义宏HAVE_POST_INCREMENT以评估为true,如果它支持后修改,则将宏定义HAVE_POST_MODIFY_DISP为true.(post-increment => ptr++,post-modify => ptr += CONST).也许还有其他一些事情需要处理.

假设您的处理器的后端已经做到了这一点,让我们转到编译包含所述修改后序列的代码时发生的情况:

有一个特定的GCC优化传递,它通过属于此类别的指令对并将它们组合在一起.该通行证的来源在这里,并且对GCC将做什么以及如何做到这一点有一个相当清楚的描述.

但最终,这不是你作为GCC用户的控制权.它是由编写GCC后端的开发人员控制的.所有你应该做的事情,就像最受欢迎的评论所说的那样:

 a = *ptr;
 ptr += SOME_CONST;
Run Code Online (Sandbox Code Playgroud)