gpt4 book ai didi

c - ASM 访问 c 结构的动态二维数组

转载 作者:太空宇宙 更新时间:2023-11-04 03:26:22 25 4
gpt4 key购买 nike

以免假设我有一个类似的结构

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

最佳答案

[rdi] is pointer to colors[0], [rdi + 8] is pointer to colors[1], but how to access colors[1][2].r and colors[1][2].g

mov  rsi,[rdi + row*8]  ; rsi = pointer to single row data

mov ax,[rsi + column*size_of_color + offset_of_r/g/b] ; value of r/g/b

根据 rdi 的用法,我猜你正在处理 64b 代码。

所以我猜 color 结构是 8B 对齐的,所以它的大小可能是 24B 而 [r, g, b] 的偏移量可能是 [ +0, +8, +16].

因此,要从 [13][7] 颜色中选择“b”值,代码将是:

mov rsi,[rdi + 13*8]
mov eax,7 * 24
mov ax,[rsi + eax + 16] ; ax = "colors[13][7].b"

为什么我对结构大小/偏移量使用“猜测”和“可能”这样的词。因为那是 C 编译器的实现和配置相关的。我相信您确实想要的是将结构紧密地打包在内存中(即大小 6B 和偏移量 [+0、+2、+4])。

搜索你的编译器指令来实现它,这里有一些 pragma documentation for gcc在这里 attributes .

struct color {
int16_t r;
int16_t g;
int16_t b;
// if you are not short of memory, consider to bump the size to 8B
// int16_t padding2B; // *8 multiplier is available in ASM addressing
// like mov ax,[rsi + ebx*8 + 2]
} __attribute__ ((packed));
// gcc will now compile this as 6B structure
// Performance warning:
// also it will stop assume anything about alignment
// so the C compiled machine code can be less optimal
// than for "unpacked" struct

正如您已经意识到的那样,二维数组在 ASM 中是 PITA,那么为什么不采用平面内存结构呢?特别是对于固定列大小为 2 的幂的情况,平面内存结构不仅代码更简单,而且由于行在连续内存中,它可能会获得相当大的性能提升。您的解决方案取决于 malloc 分配策略,并且对于碎片堆,您可能会以不同缓存页面中的每一行颜色结束,并有几个额外的缓存未命中(比平面结构)。

struct color* colors = (struct color*) malloc(rows*columns*sizeof(struct color));
colors[row * columns + column].r = 0;

那么对于 asm,您不仅必须提供指针,还必须提供 columns 大小(而且我看不出省略 rows 有什么可能有意义)。


最后的说明。你为什么不简单地用 C 编写一些访问该结构的示例,编译它,并检查生成的汇编程序,以了解如何访问结构的成员(它也可能使用一些技巧如何在 *24/etc 中执行这些操作)在您的目标平台上的快速方式)。

关于c - ASM 访问 c 结构的动态二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40870440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com