Lar*_*rry 5 linux assembly x86-64 cpu-registers att
Linux 64. AT&T.
GCC 4.8.2(-O3 -march = native)
左手下方的x86_64 abi,在第21页打开.
为了明确意图,这里有一个想法:
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]);
Run Code Online (Sandbox Code Playgroud)
检测到错误:
Error: `(%rsp,%esi,4)' is not a valid base/index expression
Run Code Online (Sandbox Code Playgroud)
代码 :
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]);
Run Code Online (Sandbox Code Playgroud)
...
start_loop:
movl (%rsp,%edx,4), (%si,%edx,4)
addl $1, %edx
cmp $4, %edx
jne start_loop
...
Run Code Online (Sandbox Code Playgroud)
我该如何表达正确的代码?我哪弄错了?
谢谢
将装配线更改为时
movl (%rsp,%rdx,4), (%rsi,%rdx,4)
我明白了
Error: too many memory references for 'mov'
什么 ??
对于读者来说,似乎我的系统非常特殊,因为它不会放置正确的指令大小.
我必须手动输入我的变量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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
560 次 |
| 最近记录: |