.asciz 和 .string 汇编程序指令之间有什么区别?

What's the difference between the .asciz and the .string assembler directives?

我知道 .ascii 指令不会在字符串的末尾放置空字符,因为 .asciz 指令用于此目的。但是,我不知道 .string 指令是否在字符串末尾放置了一个空字符。

如果它确实附加了空字符,那么 .asciz.string 指令之间有什么区别?对我来说,同时拥有 .asciz.string 似乎是多余的。

根据 binutils docs:

.ascii "string"(这里是为了完整性)

.ascii expects zero or more string literals separated by commas. It assembles each string (with no automatic trailing zero byte) into consecutive addresses.

.asciz "string"

.asciz is just like .ascii, but each string is followed by a zero byte. The “z” in ‘.asciz’ stands for “zero”.

.string "str", .string8 "str", .string16 "str", .string32 "str", .string64 "str"

Copy the characters in str to the object file. You may specify more than one string to copy, separated by commas. Unless otherwise specified for a particular machine, the assembler marks the end of each string with a 0 byte.

...

The variants string16, string32 and string64 differ from the string pseudo opcode in that each 8-bit character from str is copied and expanded to 16, 32 or 64 bits respectively. The expanded characters are stored in target endianness byte order.

它们都支持转义序列并接受多个参数。至于.string.asciz的区别:

  • 在某些体系结构中,.string 不会添加空字节,而 .asciz 总是会。要测试您自己的系统,您可以这样做:
    • echo '.string ""' | gcc -c -o stdout.o -xassembler -; objdump -sj .text stdout.o.
    • 如果第一个字节是00,则插入了空字符。
  • .string 也有将字符扩展到特定宽度(16、32 或 64)的后缀,但默认为 8。

正如问题的评论中所述,在大多数情况下,除了语义之外没有区别,但从技术上讲,这两个伪操作是不同的。

附录:

事实证明,文档 do 提到了两种行为不同的架构:

  • HPPA(惠普精密架构)- 不加 0,但有一个特殊的 .stringz 指令。
  • TI-C54X(德州仪器的一些 DSP 芯片)- 用零填充每个字(2 个字节)的高 8 位。有一个相关的 .pstring 指令,用于打包未使用的字符和零填充 space.

gas/config文件夹中挖掘源代码,我们可以确认这一点并找到一个:

  • IA64(英特尔架构)- .string.stringz 的行为类似于 HPPA。