【发布时间】:2015-10-23 13:26:28
【问题描述】:
我正在尝试学习内联汇编,并在汇编中实现了欧几里得算法!现在,当我尝试使用
运行我的代码时g++ filename -O1
它正在编译并运行良好,但是当我尝试对
做同样的事情时clang++-3.6 filename -O1
代码正在编译但产生分段错误!
当我尝试使用 -O2 或更高标志运行我的代码时,gcc 和 clang 也会产生编译时错误!
g++ 错误
eculid.cpp: Assembler messages:
eculid.cpp:19: Error: symbol `CONTD' is already defined
eculid.cpp:19: Error: symbol `DONE' is already defined
clang 错误
eculid.cpp:7:5: error: invalid symbol redefinition
"movl %1, %%eax;"
^
<inline asm>:1:34: note: instantiated into assembly here
movl %eax, %eax;movl %ecx, %ebx;CONTD: cmpl $0, %ebx;je DONE;xor...
^
eculid.cpp:7:5: error: invalid symbol redefinition
"movl %1, %%eax;"
^
<inline asm>:1:132: note: instantiated into assembly here
...%edx;idivl %ebx;movl %ebx, %eax;movl %edx, %ebx;jmp CONTD;DONE: movl %ea...
^
2 errors generated.
这是我的代码
#include <iostream>
using namespace std;
int gcd(int var1, int var2) {
int result = 0;
__asm__ __volatile__ (
"movl %1, %%eax;"
"movl %2, %%ebx;"
"CONTD: cmpl $0, %%ebx;"
"je DONE;"
"xorl %%edx, %%edx;"
"idivl %%ebx;"
"movl %%ebx, %%eax;"
"movl %%edx, %%ebx;"
"jmp CONTD;"
"DONE: movl %%eax, %0;"
:"=r"(result)
:"r"(var1), "r"(var2)
);
return result;
}
int main(void) {
int first = 0, second = 0;
cin >> first >> second;
cout << "GCD is: " << gcd(first, second) << endl;
return 0;
}
你可以检查我的代码here(我的编译器产生同样的错误)
【问题讨论】:
-
你有几个问题。您在不让 gcc 知道的情况下更改寄存器的内容,并且您没有为标签使用唯一名称。虽然我还没有运行它,但更像是(对不起格式):
__asm__ ("cmpl $0, %%ebx\n\t" "je DONE%=\n\t" "CONTD%=:\n\t" "xorl %%edx, %%edx\n\t" "idivl %%ebx\n\t" "movl %%ebx, %%eax\n\t" "movl %%edx, %%ebx\n\t" "cmpl $0, %%ebx\n\t" "jne CONTD%=\n" "DONE%=:" :"=a"(result), "+a"(var1), "+b"(var2) : /* no inputs */ : "edx");。 gcc 的内联 asm 的详细信息是 here。 -
好的,只需更改具有唯一名称的标签(通过前缀
%=)并添加已破坏寄存器列表现在我的代码甚至可以使用 -快速和-O3。感谢您的帮助,是的,这篇文章真的很棒!
标签: c++ g++ inline-assembly clang++