根据GNU Binutils 文档as https://sourceware.org/binutils/docs/as/index.html#SEC_Contents:
.ascii "string" https://sourceware.org/binutils/docs/as/Ascii.html#Ascii(此处是为了完整性)
.ascii
需要零个或多个以逗号分隔的字符串文字 [...]。它将每个字符串(没有自动尾随零字节)组装成连续的地址。
.asciz "string" https://sourceware.org/binutils/docs/as/Asciz.html#Asciz
.asciz
就像.ascii
,但每个字符串后跟一个零字节。这 ”z
" in '.asciz
' 代表“零”。
.string "str", .string8 "str", .string16 "str", .string32 "str", .string64 "str" https://sourceware.org/binutils/docs/as/String.html#String
复制其中的字符str
到目标文件。您可以指定多个要复制的字符串,并以逗号分隔。除非针对特定机器另有指定,否则汇编器用 0 字节标记每个字符串的结尾。
[...]
变体string16
, string32
and string64
不同于string
伪操作码,其中每个 8 位字符来自str
分别被复制并扩展为 16、32 或 64 位。扩展字符以目标字节顺序存储。
总而言之,之间的差异.string
and .asciz
:
-
在某些架构(如下所列)中,.string
不会添加空字节,当.asciz
一直会。要测试您自己的系统,您可以这样做:
echo '.string ""' | gcc -c -o stdout.o -xassembler -; objdump -sj .text stdout.o
如果第一个字节是00
,然后插入空字符。
-
.string
还具有将字符扩展至特定宽度(16、32 或 64)的后缀,但默认情况下为 8。
正如问题评论中所述,在简单的用例中,除了语义之外没有任何区别。它们都支持转义序列并接受多个参数。然而从技术上讲,这两个伪操作由预处理器以不同的方式处理,并且不是别名。 (对比.zero
and .skip
,这是别名。)
关于.string
,文档提到了两种行为不同的架构:
- HPPA(HP Precision Architecture)——不加0,但有一个特殊的
.stringz
指令。
- TI-C54X(德州仪器 (TI) 的 DSP 芯片) - 对每个字(2 个字节)的高 8 位进行零填充。有相关的
.pstring
打包字符并对未使用的空间进行零填充的指令。
深入挖掘源代码gas/config
文件夹中,我们可以确认这一点并找到另一个:
- IA64(英特尔架构)-
.string
and .stringz
行为类似于 HPPA。