标签和 dd 声明在 NASM 中如何工作?C 的等价物是什么?

BPL*_*BPL 2 c assembly nasm

我试图理解一些 nasm 习语的 C 等价物,如下所示:

%define CONSTANT1 1
%define CONSTANT2 2

1) section name_section data align=N
    v1: dd 1.2345678
    v2: dd 0x12345678
    v3: dd 32767
    v4:
    v5: dd 1.0
    v6:
        dd 1.0, 2.0, 3.0, 4.0,
        dd 5.0, 6.0, 7.0, 8.0

2) section name_section bss align=N
    v7:
        resd 1

3) global _function_name@0
    section name_section code align=N
    _function_name@0:
        ...

4) global _g_structure1
    global _g_structure2
    section name_section data align=N
    _g_structure1:
        dw 01h
        dw 2
    _g_structure2:
        dd CONSTANT1
        dd CONSTANT2

5) section section_name code align=N
    function_name:
        ...
Run Code Online (Sandbox Code Playgroud)

这里这里的nasm 文档没有澄清太多。我猜我的问题是:

  • 如何dd解释和类似?
  • 看起来你可以声明 N 个类型为 {code, bss, data} 的部分,并且 X 字节对齐,这在 C 中是什么意思?
  • 有些函数带有@N后缀,这是什么意思?
  • 全局...您声明全局标签吗?在什么范围内?nasm 文件,我需要什么样的程序?
  • v4:为空,什么意思?

Bee*_*ope 5

ddDWORDS存储由参数给出的序列。因此dd 1将在当前位置存储 4 字节值 0x00000001 (因为它针对的是小端架构,所以最终会得到 bytes 0x01 0x00 0x00 0x00)。

节通常不会直接在 C 中公开 - 它更多的是由编译器、链接器和运行时加载器处理的较低级别的问题。因此,一般来说,您的工具链将处理将代码和数据正确分配到各个部分中。例如,编译器会将实际汇编的代码放入.text段中,并将静态初始化的数据放入.data段中,最后将未初始化或零初始化的静态分配数据放入.bss段中,等等。这些细节实际上并不是 C 本身的一部分,并且会因平台和可执行格式而异(例如,并非所有平台都具有相同类型的节)。

另一方面,当使用汇编时,您需要更多地了解部分。例如,如果您有可变数据,那么重要的是它最终会与您的代码位于不同的部分,因为您不想遇到只读.text部分或自修改代码误报等。

节对齐是运行时加载器的指令,告诉它该节所需的最小对齐方式。您可以使用某些编译器或平台特定选项在 C 代码中影响这一点 - 例如,如果您请求静态分配的数组具有 32 对齐方式,则该.data部分可能会提升为至少 32 字节对齐方式。C 没有标准方法来实际请求这种对齐,但您可以使用特定于平台的扩展,例如posix_memalign、gcc 的aligned属性,甚至#pragma pack. 另一方面,C++11 必须alignas以标准方式执行此操作。

后缀@N是 的结果stdcall name mangling

您可以借助GLOBALnasm 中的指令声明全局标签。正如 Peter 指出的那样,这只会修改随后声明的标签的属性,而不会实际声明标签本身(仍然以通常的方式完成)。该指令还有其他特定于格式的选项,例如,您可以将导出的符号声明为函数。