我正在试图理解一些像这些类似的成语的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文档here和here没有说明太多。猜猜我的问题是:
dd
和类似物?答案 0 :(得分:3)
dd
存储由参数给出的DWORDS
序列。因此dd 1
会将4字节值0x00000001存储在当前位置(因为它以小端架构为目标,您最终会得到字节0x01 0x00 0x00 0x00
)。
部分通常不会直接暴露在C中 - 它更多是由编译器,链接器和运行时加载器处理的较低级别的问题。因此一般您的工具链将处理代码和数据的正确分配。例如,编译器会将实际汇编的代码放入.text
部分,并将静态初始化的数据放入.data
部分,最后将未初始化或零初始化的静态分配数据放入.bss
部分。 }部分,等等。细节并不是C本身的一部分,并且会因平台和可执行格式而异(例如,并非所有平台都具有相同类型的部分)。
另一方面,当使用汇编时,您需要更多地了解部分。例如,如果您有可变数据,那么它最终会与您的代码截取不同的部分,因为您不希望遇到只读.text
部分,或者自我修改代码为false积极等等。
节对齐是运行时加载程序的指令,它告诉它该节所需的最小对齐。您可以使用某些编译器或平台特定选项在C代码中对此产生影响 - 例如如果您请求静态分配的数组具有32的对齐,则.data
部分可以提升为至少32字节对齐。 C没有实际请求此类对齐的标准方法,但您可以使用特定于平台的扩展程序,例如posix_memalign
,gcc' aligned
属性,甚至是#pragma pack
。另一方面,C ++ 11有alignas
以标准方式执行此操作。
@N
后缀是stdcall name mangling
的结果。
您可以借助nasm中的GLOBAL
指令声明全局标签。正如彼得所指出的那样,这只会修改后来声明的标签的属性,并且实际上并没有声明标签本身(这仍然以通常的方式完成)。该指令具有其他format-specific options,例如,您可以将导出的符号声明为函数。
答案 1 :(得分:1)
NASM global label
指令实际上并未声明label
。它只是通过label:
来修改声明它的范围。
它与C相反,其中global是默认值,您必须使用static
来获取此编译单元专用的非导出符号。
v4:
是空的,这是什么意思?
将标签视为零宽度指针。标签本身没有大小,它只标记二进制文件中的位置。 (并且您可以在同一位置拥有多个标签)。
NASM没有类型,所以它与void*
非常相似。