在现代处理器中,可以从存储器加载寄存器,然后将索引指针后修改所需的值.例如,在我们的嵌入式处理器中,这将通过以下方式完成:
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.
是的,这是可能的.
你不应该做奇怪的指针数学来实现它.
它不仅是关于优化设置,您的GCC后端需要告诉 GCC它具有这样的功能(即当GCC本身正在编译时).基于这些知识,GCC自动将相关序列组合成单个指令.
即如果你的后端写得正确,甚至是这样的:
a = *ptr;
ptr += SOME_CONST;
Run Code Online (Sandbox Code Playgroud)
应该成为一个修改后的指令.
如何在编写后端时正确设置?(请你友好的邻居GCC后端开发人员为你做这件事):
如果您的GCC后端被调用foo:
gcc/config/foo/.foo.h包含大量#defines描述机器功能的标题.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)