linux – 汇编 – 内联asm – 从一个数组复制到另一个数组?
背景:
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; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |