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

标签和dd声明在NASM中如何工作?什么';C的等价物是什么?,c,assembly,nasm,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

我试图理解一些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:
        ...
nasm的文档并没有澄清太多。我想我的问题是:

  • 如何解释
    dd
    和类似词
  • 似乎可以用X字节对齐方式声明N个{code,bss,data}类型的节,这在C中是什么意思
  • 有带@N后缀的函数,这是什么意思
  • 全球。。。您是否声明全局标签?在什么范围内?nasm文件
  • 是空的,这是什么意思

dd
存储参数给定的
DWORD序列。因此,
dd1
将在当前位置存储4字节的值0x00000001(因为它的目标是一个小的endian体系结构,您将得到字节
0x01 0x00 0x00 0x00

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

另一方面,在使用assembly时,您需要更加了解小节。例如,如果您有可变数据,则重要的是它的结尾与您的代码不同,因为您不希望遇到只读
.text
部分或自修改代码误报等

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

@N
后缀是由以下原因造成的


您可以在nasm中的
global
指令的帮助下声明全局标签。正如Peter指出的那样,这只修改了随后声明的标签的属性,实际上并没有声明标签本身(这仍然是以通常的方式进行的)。该指令还有其他功能,例如,可以将导出的符号声明为函数

dd
存储参数给定的
DWORDS
序列。因此,
dd1
将在当前位置存储4字节的值0x00000001(因为它的目标是一个小的endian体系结构,您将得到字节
0x01 0x00 0x00 0x00

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

另一方面,在使用assembly时,您需要更加了解小节。例如,如果您有可变数据,则重要的是它的结尾与您的代码不同,因为您不希望遇到只读
.text
部分或自修改代码误报等

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

@N
后缀是由以下原因造成的


您可以在nasm中的
global
指令的帮助下声明全局标签。正如Peter指出的那样,这只修改了随后声明的标签的属性,实际上并没有声明标签本身(这仍然是以通常的方式进行的)。该指令还有其他功能,例如,可以将导出的符号声明为函数

NASM
全局标签
指令实际上没有声明
标签
。它只是修改了当您使用
label:
声明它时它将拥有的范围

它与C相反,全局是默认值,您必须使用
static
获取此编译单元专用的未导出符号


v4:
为空,这是什么意思

将标签视为零宽度指针。标签本身没有大小,它只是在二进制文件中标记该位置。(在同一位置可以有多个标签)

NASM没有类型,因此它实际上与NASM非常相似