【发布时间】:2017-04-13 17:14:12
【问题描述】:
免得假设我有一个类似的结构
struct color {
int16_t r;
int16_t g;
int16_t b;
};
还有一个点数组
struct color** colors = (struct color**) malloc(rows*sizeof(struct color*));
for (int i=0; i < rows; i++) {
colors[i] = (struct color*) malloc(columns*sizeof(struct color));
for (int j=0; j < columns; j++) {
colors[i][j].r=0;
colors[i][j].g=0;
colors[i][j].b=0;
}
}
我想把它传递给一个函数
void some_function(struct color** colors);
颜色现在在 rdi 上。我想在 assambler 中迭代该数组并将 1 添加到 r、2 到 g 和 3 到 b。我知道 rdi 是指向颜色的指针,[rdi] 是指向颜色 [0] 的指针,[rdi + 8] 是指向颜色 [1] 的指针,但是如何访问颜色 [1][2].r 和颜色 [1 ][2].g
【问题讨论】:
-
取消引用更多并应用适当的偏移量。如果您使用指针而不是索引重写 C 代码,您可能会更好地理解它,然后您可以将其直接转换为 asm。 (不要忘记 C 指针算术会自动缩放,但在 asm 中您使用字节偏移量。)
-
C 代码中没有二维数组,注意哪个可以指向一个或代表一个!指针不是数组。
-
OTOH 用 C 定义的二维数组将以“平面”内存模型结尾,因此它不能与他的解决方案互换。但我同意,他有指向行的指针列表。奇怪的低效设计。
-
你有没有考虑在 gcc 中使用 -S 选项并查看它生成的 asm 代码?
-
如果您关心性能,您可能需要将指向行的指针数组重新设计为单个平面数组。 SSE2 / AVX2 将在一个大缓冲区而不是每行单独的数组上工作得更好。