什么是运算符 new(unsigned int)?

逆向工程 拆卸 C++ 海湾合作委员会
2021-06-25 10:14:26

在反汇编器输出(ARM)中,我看到:

    BLX _Znwj

哪里BLX是 ARM 过程调用并被_Znwj分解为

$ c++filt  _Znwj
operator new(unsigned int)

那有什么作用operator newnew还是new[]它返回什么类型?我如何从 C++ 中显式调用它,某种operator+(a,b)风格?

(我知道可以operator new在类中定义,但这看起来有点不同。)

2个回答

运行时函数不一定转换为 C++ 函数。例如,在没有浮点硬件的处理器上,像这样的简单语句

a=b+c;

ab并且c被浮动,可能会被转换为函数调用需要bc作为参数并返回结果。用户不应直接调用该函数。

在您的情况下,请考虑每个new可能映射到分配内存并调用构造函数的对象,并且每个都new[]为多个元素分配内存并在每个元素上调用构造函数。new _Znwj函数是new操作员内部使用的内存分配器(至少如果您使用的gcc是我假设的),并且它不打算直接从 C++ 调用。

这个程序:

    class Foo {
            int bar;
    };

    int main(void) {
            Foo *baz=new Foo();
            Foo *var=new Foo[20];
    }

编译为(尝试gcc -S):

    stmfd   sp!, {fp, lr}
    .save {fp, lr}
    .setfp fp, sp, #4
    add     fp, sp, #4
    .pad #8
    sub     sp, sp, #8
    mov     r0, #4                <-- 4 bytes for single variable
    bl      _Znwj
    mov     r3, r0                <-- r0 returns the pointer to the allocated memory
    mov     r2, #0
    str     r2, [r3]
    str     r3, [fp, #-8]
    mov     r0, #80               <-- 80 bytes (20*4) for array
    bl      _Znaj
    mov     r3, r0                <-- r0 returns the pointer to the allocated memory
    str     r3, [fp, #-12]
    mov     r3, #0
    mov     r0, r3
    sub     sp, fp, #4
    @ sp needed
    ldmfd   sp!, {fp, lr}
    bx      lr

所以,你看到了_Znwj_Znaj是单个类的分配器函数。一个类数组,它们都将所需的字节数作为参数,并且它们都返回一个指向已分配内存的指针作为结果。

回答您的问题:

  1. 那个操作员是new做什么的?

    它为新的类实例分配内存。

  2. new还是new[]

    _Znwjnew,并且_Znajnew[]

  3. 它返回什么类型?

    它返回新分配的内存块的地址。在 C++ 中,最接近的匹配是 a void *,但请注意它应该指向一个类结构。

  4. 我如何从 C++ 中显式调用它,operator+(a,b)风格中的东西

    你不应该那样做。您使用newnew[]我假设gcc明确使用的函数名称的制造者通常无法从 C++ 程序中调用而不会由于名称冲突而出现语法错误。

这称为“放置new”,是在 C++03 中引入的。它的工作方式是,可以有一个 C++ 类围绕一组硬件寄存器,然后使用放置new将类准确地放在这些硬件寄存器之上。例如,如果一个基于硬件的硬件随机数发生器 (RNG) 是使用 32 位控制寄存器、状态寄存器和数据寄存器定义的,它们都从偏移 0x50000600 开始,您可以定义一个类:

class RNG_class
{
private:
  volatile uint32_t CR;  // set to 1 to enable
  volatile uint32_t SR;  // low bit set when next num available
  volatile uint32_t DR:
public;
  RNG_class() : CR(1) {} 
  uint32_t next() { while (SR&1 == 0); return DR; }
};

在其他地方,则可以将此类实例化为

RNG_class RNG* = new(0x50000600) RNG_class();

并且可以将其用作:

r = RNG->next();

有关更多信息,请参阅此问题