Search code examples
assemblyx86gnu-assembler

ascii vs asciz vs string in gas


What is the difference between .ascii, .asciz, and .string in gas? It seems clear to me that:

  • .ascii is something like char[], so .ascii "hello" would translate to 0x48 0x65 0x6c, 0x6c, 0x6f.
  • .asciz is the same but adds a nul to the end, so .asciz "hello" would translate to 0x48 0x65 0x6c, 0x6c, 0x6f 0x00.

But then what is the difference of .string vs. the two above and why would one be used over the other?


Solution

  • GAS has multiple aliases for various directives for compatibility with Unix assemblers on various platforms. This is the primary reason for redundant directives for the same thing.

    Some of those aliases mean different things depending on the target platform; generally avoid those when there's a same-everywhere way, e.g. always use .balign or .p2align, never .align. Always use .ascii or .asciz, never .string.

    That way you (and future readers of your code) can just look up what it means in the GAS manual, without having to check on which way it behaves for some specific target platform.


    As documented in the GAS manual for .string (which you should read in future when you're wondering about other directives):

    Unless otherwise specified for a particular machine, the assembler marks the end of each string with a 0 byte.

    So on most targets, it's a synonym for .asciz. But apparently on some, it's a synonym for .ascii.

    There are .string16, .string32, and .string64 directives in case you want strings of wide characters. In that case maybe worth putting up with the possible ambiguity of zero-termination, as long as you know what it does on the ISA you're actually targeting with this source file. I don't think there are equivalents for asciz.