加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – 汇编 – 内联asm – 从一个数组复制到另一个数组?

发布时间:2020-12-14 01:02:10 所属栏目:Linux 来源:网络整理
导读:背景: Linux 64. AT T. GCC 4.8.2(-O3 -march = native) 左手下方的x86_64 abi,??在第21页打开. 预期的C代码: 为了明确意图,这里有一个想法: int32_t res[] = {0,0};int32_t primo[] = {5,8,50,150};for (int32_t x = 0; x 4; ++x) { res[x] = primo[x];}
背景:

Linux 64. AT& T.

GCC 4.8.2(-O3 -march = native)

左手下方的x86_64 abi,??在第21页打开.

预期的C代码:

为了明确意图,这里有一个想法:

int32_t res[] = {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 %dn",res[0],res[1],res[2],res[3]);

有缺陷的C代码:

检测到错误:

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

代码 :

int32_t res[] = {0,150};
int32_t counter = 0;

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

printf("%d %d %d %dn",res[3]);

汇编代码(问题背后的线条):

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

问题:

我该如何表达正确的代码?我哪弄错了?

谢谢

更新:

将装配线更改为时

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

我明白了

错误:’mov’的内存引用太多

什么 ??

更新2

对于读者来说,似乎我的系统非常特殊,因为它不会放置正确的指令大小.

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

否则,gcc会粘贴32位版本,导致无效的基本/索引错误.

它多次咬我.我希望现在不适合你.

解决方法

现在关闭ABI文档,并打开intel手册,基本架构和指令集参考当然: – >

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

gcc内联汇编是一件非常复杂的事情.如果可能的话,最好避免使用它,特别是如果你是初学者,否则你将与编译器对抗而不是学习汇编.

固定版本可能如下所示:

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

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

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

    printf("%d %d %d %dn",res[3]);
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读