- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在GCC中使用内联汇编。我想将变量内容向左旋转2位(我将变量移至rax寄存器,然后将其旋转2次)。我在下面编写了代码,但遇到了分段错误(核心转储)错误。
如果您能帮助我,我将不胜感激。
uint64_t X = 13835058055282163712U;
asm volatile(
"movq %0 , %%rax\n"
"rol %%rax\n"
"rol %%rax\n"
:"=r"(X)
:"r"(X)
);
printf("%" PRIu64 "\n" , X);
最佳答案
理解内联汇编的关键是要理解每个汇编语句都有两个部分:
实际的汇编程序内容的文本,编译器将在其中进行文本替换,但无法理解。
这是文档中的AssemblerTemplate(直到:
中第一个__asm__()
的所有内容)。
用编译器确实了解的术语来描述汇编程序的工作。
这是the documentation中的: OutputOperands : InputOperands : Clobbers
。
这必须告诉编译器汇编器如何适合编译器围绕它生成的所有代码。代码生成正忙于分配寄存器来保存值,确定执行操作的顺序,将内容移出循环,消除未使用的代码片段,丢弃不再需要的值,等等。
实际的汇编程序是一个黑匣子,它接收此处描述的输入,产生所描述的输出,并且副作用可能是“堆积”一些寄存器和/或存储器。这必须是对汇编器功能的完整描述...否则,编译器在模板周围生成的asm将与其冲突并依赖错误的假设。
有了这些信息,编译器就可以决定汇编器可以使用哪些寄存器,您应该让它这样做。
因此,您的片段:
asm volatile(
"movq %0 , %%rax\n"
"rol %%rax\n"
"rol %%rax\n"
:"=r"(X)
:"r"(X)
);
%rax
,并且可能希望在
%rax
中返回结果-事实并非如此。
%rax
,编译器可能已经将它分配给了其他内容……因此,实际上,您正在“窃听”
%rax
,但是您没有告诉编译器!
=r(X)
(OutputOperand),它告诉编译器期望某个寄存器中的输出,并且该输出将是变量
X
的新值。 AssemblerTemplate中的
%0
将替换为为输出选择的寄存器。可悲的是,您的程序集将
%0
视为输入:-(并且输出实际上是在
%rax
中-如上所述,编译器没有意识到。
r(X)
(InputOperand),它告诉编译器安排将变量
X
的当前值放在某个寄存器中,以供汇编器使用。在AssemblerTemplate中为
%1
。可悲的是,您的程序集不使用此输入。
X
,编译器也可能不会将
%0
设置为与
%1
相同的寄存器。 (这允许它将asm块用作非破坏性操作,使输入的原始值保持不变。如果这不是模板的工作方式,请不要这样写。
volatile
。如果没有使用所有输出,编译器将做的一件好事就是丢弃一个
asm()
...
volatile
告诉编译器不要这样做(并告诉它许多其他事情) ...请参阅手册)。
mov
指令:
asm("rol %0\n"
"rol %0\n" : "+r"(X));
"+r"(X)
表示需要一个组合的输入和输出寄存器,取旧值
X
并返回一个新值。
X
,那么假设结果为
Y
,则可以:
asm("mov %1, %0\n"
"rol %0\n"
"rol %0\n" : "=r"(Y) : "r"(X));
mov
还是只允许销毁输入。
asm()
之后不再使用给定的InputOperand时,这很重要,因此编译器可以将InputOperand的寄存器分配给OutputOperand。有一种叫做Earlyclobber(
=&r(foo)
)的东西可以处理这种小皱纹。
X
,则编译器可以将
%0
和
%1
分配给同一寄存器!但是(冗余)
mov
仍将被汇编-记住编译器确实不理解AssemblerTemplate。因此,通常最好改掉C中的值,而不是
asm()
。请参见
https://gcc.gnu.org/wiki/DontUseInlineAsm和
Best practices for circular shift (rotate) operations in C++
// (1) uses both X and Y in the printf() -- does mov %1, %0 in asm()
void Never_Inline footle(void) Dump of assembler code for function footle:
{ mov $0x492782,%edi # address of format string
unsigned long X, Y ; xor %eax,%eax
mov $0x63,%esi # X = 99
X = 99 ; rol %rsi # 1st asm
__asm__("\t rol %0\n" rol %rsi
"\t rol %0\n" : "+r"(X) mov %rsi,%rdx # 2nd asm, compiler using it as a copy-and-rotate
) ; rol %rdx
rol %rdx
__asm__("\t mov %1, %0\n" jmpq 0x4010a0 <printf@plt> # tailcall printf
"\t rol %0\n"
"\t rol %0\n" : "=r"(Y) : "r"(X)
) ;
printf("%lx %lx\n", X, Y) ;
}
// (2) uses both X and Y in the printf() -- does Y = X in 'C'
void Never_Inline footle(void) Dump of assembler code for function footle:
{ mov $0x492782,%edi
unsigned long X, Y ; xor %eax,%eax
mov $0x63,%esi
X = 99 ; rol %rsi # 1st asm
__asm__("\t rol %0\n" rol %rsi
"\t rol %0\n" : "+r"(X) mov %rsi,%rdx # compiler-generated mov
) ; rol %rdx # 2nd asm
rol %rdx
Y = X ; jmpq 0x4010a0 <printf@plt>
__asm__("\t rol %0\n"
"\t rol %0\n" : "+r"(Y)
) ;
printf("%lx %lx\n", X, Y) ;
}
// (3) uses only Y in the printf() -- does mov %1, %0 in asm()
void Never_Inline footle(void) Dump of assembler code for function footle:
{ mov $0x492782,%edi
unsigned long X, Y ; xor %eax,%eax
mov $0x63,%esi
X = 99 ; rol %rsi
__asm__("\t rol %0\n" rol %rsi
"\t rol %0\n" : "+r"(X) mov %rsi,%rsi # redundant instruction because of mov in the asm template
) ; rol %rsi
rol %rsi
__asm__("\t mov %1, %0\n" jmpq 0x4010a0 <printf@plt>
"\t rol %0\n"
"\t rol %0\n" : "=r"(Y) : "r"(X)
) ;
printf("%lx\n", Y) ;
}
// (4) uses only Y in the printf() -- does Y = X in 'C'
void Never_Inline footle(void) Dump of assembler code for function footle:
{ mov $0x492782,%edi
unsigned long X, Y ; xor %eax,%eax
mov $0x63,%esi
X = 99 ; rol %rsi
__asm__("\t rol %0\n" rol %rsi
"\t rol %0\n" : "+r"(X) rol %rsi # no wasted mov, compiler picked %0=%1=%rsi
) ; rol %rsi
jmpq 0x4010a0 <printf@plt>
Y = X ;
__asm__("\t rol %0\n"
"\t rol %0\n" : "+r"(Y)
) ;
printf("%lx\n", Y) ;
}
:
OutputOperands
:
InputOperands
:
Clobbers是您在描述汇编程序正在执行的操作的地方。
关于c - 使用内联汇编时出现段错误(核心转储)错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60237447/
我已经使用 vue-cli 两个星期了,直到今天一切正常。我在本地建立这个项目。 https://drive.google.com/open?id=0BwGw1zyyKjW7S3RYWXRaX24tQ
您好,我正在尝试使用 python 库 pytesseract 从图像中提取文本。请找到代码: from PIL import Image from pytesseract import image_
我的错误 /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference
我已经训练了一个模型,我正在尝试使用 predict函数但它返回以下错误。 Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]])
根据Microsoft DataConnectors的信息我想通过 this ODBC driver 创建一个从 PowerBi 到 PostgreSQL 的连接器使用直接查询。我重用了 Micros
我已经为 SoundManagement 创建了一个包,其中有一个扩展 MediaPlayer 的类。我希望全局控制这个变量。这是我的代码: package soundmanagement; impo
我在Heroku上部署了一个应用程序。我正在使用免费服务。 我经常收到以下错误消息。 PG::Error: ERROR: out of memory 如果刷新浏览器,就可以了。但是随后,它又随机发生
我正在运行 LAMP 服务器,这个 .htaccess 给我一个 500 错误。其作用是过滤关键字并重定向到相应的域名。 Options +FollowSymLinks RewriteEngine
我有两个驱动器 A 和 B。使用 python 脚本,我在“A”驱动器中创建一些文件,并运行 powerscript,该脚本以 1 秒的间隔将驱动器 A 中的所有文件复制到驱动器 B。 我在 powe
下面的函数一直返回这个错误信息。我认为可能是 double_precision 字段类型导致了这种情况,我尝试使用 CAST,但要么不是这样,要么我没有做对...帮助? 这是错误: ERROR: i
这个问题已经有答案了: Syntax error due to using a reserved word as a table or column name in MySQL (1 个回答) 已关闭
我的数据库有这个小问题。 我创建了一个表“articoli”,其中包含商品的品牌、型号和价格。 每篇文章都由一个 id (ID_ARTICOLO)` 定义,它是一个自动递增字段。 好吧,现在当我尝试插
我是新来的。我目前正在 DeVry 在线学习中级 C++ 编程。我们正在使用 C++ Primer Plus 这本书,到目前为止我一直做得很好。我的老师最近向我们扔了一个曲线球。我目前的任务是这样的:
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我的网站中有一段代码有问题;此错误仅发生在 Internet Explorer 7 中。 我没有在这里发布我所有的 HTML/CSS 标记,而是发布了网站的一个版本 here . 如您所见,我在列中有
如果尝试在 USB 设备上构建 node.js 应用程序时在我的树莓派上使用 npm 时遇到一些问题。 package.json 看起来像这样: { "name" : "node-todo",
在 Python 中,您有 None单例,在某些情况下表现得很奇怪: >>> a = None >>> type(a) >>> isinstance(a,None) Traceback (most
这是我的 build.gradle (Module:app) 文件: apply plugin: 'com.android.application' android { compileSdkV
我是 android 的新手,我的项目刚才编译和运行正常,但在我尝试实现抽屉导航后,它给了我这个错误 FAILURE: Build failed with an exception. What wen
谁能解释一下?我想我正在做一些非常愚蠢的事情,并且急切地等待着启蒙。 我得到这个输出: phpversion() == 7.2.25-1+0~20191128.32+debian8~1.gbp108
我是一名优秀的程序员,十分优秀!