gpt4 book ai didi

linux - 程序集 - 内联 asm - 从一个数组复制到另一个数组?

转载 作者:IT王子 更新时间:2023-10-29 01:21:40 25 4
gpt4 key购买 nike

上下文:

Linux 64.AT&T。

GCC 4.8.2(带 -O3 -march=native)

我左手下的x86_64 abi,​​在第21页打开。

预期的 C 代码:

为了明确意图,这里是想法:

int32_t res[] = {0,0,0,0};
int32_t primo[] = {5,8,50,150};

for (int32_t x = 0; x < 4; ++x) {

res[x] = primo[x];
}

printf("%d %d %d %d\n", res[0], res[1], res[2], res[3]);

错误的C代码:

检测到错误:

Error: `(%rsp,%esi,4)' is not a valid base/index expression

代码:

int32_t res[] = {0,0,0,0};
int32_t primo[] = {5,8,50,150};
int32_t counter = 0;

__asm__ volatile(
"start_loop:\n\t"
"movl (%1,%2,4), (%0,%2,4)\n\t"
"addl $1, %2\n\t"
"cmp $4, %2\n\t"
"jne start_loop"
: "=&r"(res)
: "r"(primo),"r"(counter)
:"cc"
);

printf("%d %d %d %d\n", res[0], res[1], res[2], res[3]);

汇编代码(问题所在的行):

...
start_loop:
movl (%rsp,%edx,4), (%si,%edx,4)
addl $1, %edx
cmp $4, %edx
jne start_loop
...

问题:

如何表达正确的代码?我哪里做错了?

谢谢

更新:

将流水线改成

movl (%rsp,%rdx,4), (%rsi,%rdx,4)

我明白了

错误:“mov”的内存引用过多

什么??

更新2

对于读者来说,似乎我的系统很特别,因为它不会放入正确的指令大小。

我必须以 int64_t 为例手动键入我的变量,以强制 r*x 事件发生。如果 c11/c++11 使用 uintptr_t 类型。

否则,gcc 会坚持使用 32 位版本,这会导致无效的基数/索引错误。

它咬了我好几次。我希望它现在不会适合你。

最佳答案

现在关闭 ABI 文档,打开 intel 手册、基本架构和指令集引用:->

首先,mov 不接受两个内存操作数,您必须通过寄存器或使用专门的字符串移动movs。其次,在有效地址中不能混合使用 16、32 和 64 位寄存器。鉴于您的代码片段中的类型,编译器为您替换了 16 位寄存器非常可疑。此外,由于不可能的约束,它甚至不应该编译,res 是一个数组,你不能将它用作输出。此外,您正在更改 counter 变量,但您没有告诉编译器。

gcc 内联汇编是一个非常复杂的东西。如果可能,最好避免使用它,尤其是如果您是初学者,否则您将与编译器作斗争而不是学习汇编。

固定版本可能如下所示:

#include <stdint.h>
#include <stdio.h>

int main()
{
int32_t res[] = {0,0,0,0};
int32_t primo[] = {5,8,50,150};
int32_t counter = 0;
int32_t tmp;

__asm__ volatile(
"start_loop:\n\t"
"movl (%3, %q1, 4), %0\n\t"
"movl %0, (%2, %q1, 4)\n\t"
"addl $1, %1\n\t"
"cmp $4, %1\n\t"
"jne start_loop"
: "=&r" (tmp), "+r" (counter)
: "r" (res), "r"(primo)
: "cc", "memory"
);

printf("%d %d %d %d\n", res[0], res[1], res[2], res[3]);
return 0;
}

关于linux - 程序集 - 内联 asm - 从一个数组复制到另一个数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28645466/

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