小编new*_*bie的帖子

为什么ARM PC寄存器指向下一个要执行的指令后?

根据ARM IC.

在ARM状态下,PC的值是当前指令的地址加上8个字节.

在Thumb状态:

  • 对于B,BL,CBNZ和CBZ指令,PC的值是当前指令的地址加上4个字节.
  • 对于使用标签的所有其他指令,PC的值是当前指令的地址加上4个字节,结果的位[1]清零以使其字对齐.

简单地说,PC寄存器的值指向下一条指令后的指令.这是我没有得到的.通常(特别是在x86上)程序计数器寄存器用于指向要执行的下一条指令的地址.

那么,底层的前提是什么?有条件执行,也许?

assembly arm

33
推荐指数
1
解决办法
2万
查看次数

std :: move如何复制不可复制的对象?

请考虑以下代码.

#include <iostream>
#include <type_traits>

struct A
{
    int x;
    A() = default;
    ~A() = default;

    A(const A&) = delete;
    A &operator=(const A&) = delete;

    A(A &&) = default;
    A &operator=(A &&a) = default;
};

int main()
{
    std::cout << std::boolalpha;
    std::cout << std::is_copy_constructible<A>::value << std::endl;
    std::cout << std::is_copy_assignable<A>::value << std::endl;

    A a;
    a.x = 3;

    A b = std::move(a);

    std::cout << std::hex << a << " " << &b << std::endl;
    std::cout << a.x << " " << b.x; …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11

3
推荐指数
2
解决办法
1230
查看次数

x86 ENTER指令有什么问题?

考虑x86指令ENTER.来自英特尔的指令集参考.

为过程创建堆栈帧.第一个操作数(大小操作数)指定堆栈帧的大小(即,为该过程在堆栈上分配的动态存储的字节数).第二个操作数(嵌套级别操作数)给出过程的词法嵌套级别(0到31).嵌套级别确定从前一帧复制到新堆栈帧的"显示区域"的堆栈帧指针的数量.这两个操作数都是立即值.

我想知道ENTER当非零嵌套级别作为第二个操作数传递时,指令是如何工作的.在这种情况下,根据英特尔的手册,处理器应该在堆栈上推送额外的帧指针.听起来很简单,但我无法理解为什么它在样本程序中无法正常工作.

我使用FASM编译了以下示例,并使用OllyDbg进行了调试.

format PE

section '.text' code readable executable
entry start
start:
    enter 16, 8
    push 0
    call ExitProcess
...
Run Code Online (Sandbox Code Playgroud)

ENTER下面给出了指令发出的堆栈帧.

000CFF58   00000000 ; new esp
000CFF5C   00000000
000CFF60   00000000
000CFF64   00000000
000CFF68   000CFF88 ; value of new ebp
000CFF6C   7EFDE000 ; ?
000CFF70   000CFF94 ; value of old ebp
000CFF74   76AD338A ; ?
000CFF78   7EFDE000 ; ?
000CFF7C   000CFF94 ; value of old ebp
000CFF80   76AD338A ; ?
000CFF84   7EFDE000 ; ? …
Run Code Online (Sandbox Code Playgroud)

x86 assembly

2
推荐指数
1
解决办法
957
查看次数

在这种情况下,将基类的对象强制转换为EMPTY派生类是不安全的

我使用以下代码来访问对象的受保护成员.

class Base {
protected:
    void foo();
};

class PublicBase : public Base {
public:
    static void bar(Base *obj) {
        static_assert(sizeof(PublicBase) == sizeof(Base), "Not today");
        static_cast<PublicBase *>(obj)->foo();
    }
};
Run Code Online (Sandbox Code Playgroud)

我可以假设提供的代码是安全的(理论上和实践中)吗?

c++

2
推荐指数
1
解决办法
79
查看次数

迭代但不解除引用C++中的无效迭代器

当使用Visual C++编译器在调试模式下编译时,此代码调用一个断言.

std::vector<int> test;
++test.begin();
Run Code Online (Sandbox Code Playgroud)

该计划说:

Debug Assertion Failed!

...

Expression: vector iterator not incrementable.
Run Code Online (Sandbox Code Playgroud)

至于我,这段代码是完全合法的,因为我不打算取消引用迭代器.问题是:标准是否未定义(或可能是实现定义)此行为?

c++ visual-c++

2
推荐指数
1
解决办法
384
查看次数

标签 统计

c++ ×3

assembly ×2

arm ×1

c++11 ×1

move-semantics ×1

visual-c++ ×1

x86 ×1