看完这个堆栈溢出的答案,而这个文件,我还是不明白之间的差别movq和movabsq.
我目前的理解是movabsq,第一个操作数是一个64位立即数操作数,而movq符号扩展一个32位立即数操作数.从上面引用的第二个文件:
将立即数据移动到64位寄存器可以通过
movq指令进行,该指令将签署扩展32位立即值,或者movabsq在需要完整的64位立即数时使用指令.
在第一篇参考文献中,彼得说:
有趣的实验:
movq $0xFFFFFFFF, %rax可能不可编码,因为它不能用符号扩展的32位立即数表示,并且需要imm64编码或%eax目标编码.
但是,当我组装/运行它时似乎工作正常:
.section .rodata
str:
.string "0x%lx\n"
.text
.globl main
main:
pushq %rbp
movq %rsp, %rbp
movl $str, %edi
movq $0xFFFFFFFF, %rsi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbp
ret
Run Code Online (Sandbox Code Playgroud)
$ clang file.s -o file && ./file
打印0xffffffff.(这适用于较大的值,例如,如果你输入一些额外的"F").movabsq生成相同的输出.
Clang是在推断我想要的吗?如果是,是否有仍然是受益movabsq过度movq?
我错过了什么?
我为冗长的标题道歉,但我无法简洁地表达这个问题。
我有一个带有deleted 复制构造函数和复制赋值运算符的类。当我尝试使用类的实例初始化数组时,除非我提供移动构造函数,否则我会收到编译器错误。但是,提供的移动构造函数实际上并未被调用。
这是一个 MWE 说明了这个问题。
#include <cstdio>
#include <string>
class A
{
public:
explicit A(std::string s) : s_(s) { puts("constructor"); }
A() = delete;
~A() = default;
A(const A &other) = delete;
A &operator=(const A &other) = delete;
// A(A &&other) : s_(std::move(other.s_)) { puts("move constructor"); }
void print_s() { printf("%s\n", s_.c_str()); }
private:
std::string s_;
};
int main()
{
A arr[]{A{"some"}, A{"string"}};
for (auto &a : arr) {
a.print_s();
}
}
Run Code Online (Sandbox Code Playgroud)
如图所示注释掉移动构造函数,我收到错误消息:
> g++ file.cc -g …Run Code Online (Sandbox Code Playgroud)