- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在我看来,clang++ 错过了 g++ 拾取的汇编代码中的错误。还是我缺少一些 clang 的编译器标志?我是汇编代码的新手。
我使用 clang++ 编译并链接了我的应用程序,没有错误和警告,但我遇到了严重的段错误。切换到 g++,另一方面,我遇到了这些错误:
GO_F_ImageColourConversion.cpp: Assembler messages:
GO_F_ImageColourConversion.cpp:4679: Error: `(%rsi,%edx,2)' is not a valid base/index expression
GO_F_ImageColourConversion.cpp:4682: Error: `(%rcx,%edx,1)' is not a valid base/index expression
我正在使用这些编译器标志:-DLINUX -g -Wno-deprecated -D_GNU_SOURCE -D_REENTRANT -D__STDC_CONSTANT_MACROS -fPIC -fPIE
我有以下代码(省略不相关的部分):
Ipp8u * pSrc;
Ipp8u * pDst;
int x, y;
asm volatile
(
"movl (%1, %0, 2), %%eax;\n"
"shlw $8, %%ax;\n"
"shrl $8, %%eax;\n"
"movw %%ax, (%2, %0, 1);\n"
: /* no output */
: "r" (x), "r" (pSrc), "r" (pDst)
: "eax", "memory");
}
从看这个answer on SO ,我意识到我有一个 32/64 位问题(我正在移植到 64 位)。Ipp8u* 是 8 位,但在我的机器上只有 4 位。
将 int 更改为 uintptr_t x, y;
似乎可以解决问题。为什么 clang 在编译时不报错?
最佳答案
gcc 和 clang 都对我的代码感到窒息:
6 : error: base register is 64-bit, but index register is not
"movl (%1, %0, 2), %%eax\n"
^
<inline asm>:1:13: note: instantiated into assembly here
movl (%rdi, %edx, 2), %eax
来自 clang 3.8 on the godbolt compiler explorer ,它周围有一个函数,所以它是可测试的,你在问题中没有提供。您确定您的 clang 正在构建 64 位代码吗? (-m64
,不是 -m32
或 -mx32
)。
在 Godbolt 上提供指向您的代码的链接,某些版本的 clang 会默默地错误编译它,否则对于您的实际问题我只能说“无法重现”。
是的,您的问题是 x
是一个 int
,您的问题是寻址模式下的混合寄存器大小。 (%rsi,%edx,2)
不可编码。
使用 %q0
获取 %rdx
并不能保证寄存器的高 32 位中没有垃圾(尽管这种可能性很小)。相反,您可以使用 "r"((int64_t)x)
到 sign-extend x
to 64bits .
为什么您需要内联汇编?您的 C 版本的编译器输出有多糟糕?
如果您确实想使用内联 asm,这好得多:
uint32_t asm_tmp = *(uint32_t *)(x*2 + (char*)pSrc); // I think I've reproduced the same pointer math as the addressing mode you used.
asm ( "shlw $8, %w[v]\n\t" // e.g. ax
"shrl $8, %k[v]\n\t" // e.g. eax. potential partial-register slowdown from reading eax after writing ax on older CPUs
: [v] "+&r" (asm_tmp)
);
*(uint16_t *)(x + (char*)pDst) = asm_tmp; // store the low 16
这可以用 clang 很好地编译,但是 gcc is kinda braindead about generating the address .也许地址有不同的表达方式?
您的代码以加载开始并以存储结束,从而违背了约束的目的。总是让编译器尽可能多地处理。如果没有内联 asm,您可能会从中获得更好的代码,并且编译器会理解它的作用,并且可能会自动矢量化或进行其他转换。使用 "memory"
clobber 消除 asm 语句成为 volatile
的需要对优化器来说已经是一个很大的改进:现在它是一个编译器只知道转换的纯函数一个寄存器。
另见 the end of this answer有关编写不差劲的内联 asm 的更多指南。
关于linux - clang 错过汇编程序错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36885777/
我正在使用 Azure 函数处理来自 IOT 中心的消息并将其输出到 Blob 存储。 enter image description here 但是当我高频发送时,该功能丢失了 IOT 消息。例如,
我正在尝试使用 mediasoup 通过 room.createRtpStreamer 转发 RTP 流 我的问题是我从 producer.rtpParameters.codecs[i].payloa
我正在尝试使用 mediasoup 通过 room.createRtpStreamer 转发 RTP 流 我的问题是我从 producer.rtpParameters.codecs[i].payloa
我正在使用 Spring 应用程序事件将信息发送到其他 bean。有一个 bean A,一旦 A 初始化,它就会发布一个事件。并且有一个 bean B 监听 A 发送的事件。 根据 A 在其他 Bea
CMake 有 Qt4 的特殊变量 ${QT_DEFINITIONS},其中包含 QT 定义,例如 QT_NO_DEBUG 和 QT_DEBUG。 Qt5 没有这样的选项。 如何在 cmake 中添加
我是一名优秀的程序员,十分优秀!