Posted on

When a var really isn't a var - part 2

This is a small follow up to my previous post about vars and consts.

In my post I was wonder why var input = "Hello Zig".* would let me edit it input[0] = 'a', for example, when string literals are constants.
As pointed out by @kristoff , turns out "Literal".* creates a copy on the stack.

This can be verified by looking at the generated assembly (x86_64 atleast)

0000000000225aa0 <main>:
  225aa0:   55                      push   rbp
  225aa1:   48 89 e5                mov    rbp,rsp
  225aa4:   48 83 ec 20             sub    rsp,0x20
  225aa8:   48 8b 04 25 e2 38 20    mov    rax,QWORD PTR ds:0x2038e2
  225aaf:   00
  225ab0:   48 89 45 f6             mov    QWORD PTR [rbp-0xa],rax
  225ab4:   66 8b 04 25 ea 38 20    mov    ax,WORD PTR ds:0x2038ea
  225abb:   00
  225abc:   66 89 45 fe             mov    WORD PTR [rbp-0x2],ax
  225ac0:   48 8b 45 f6             mov    rax,QWORD PTR [rbp-0xa]
  225ac4:   48 89 45 e8             mov    QWORD PTR [rbp-0x18],rax
  225ac8:   66 8b 45 fe             mov    ax,WORD PTR [rbp-0x2]
  225acc:   66 89 45 f0             mov    WORD PTR [rbp-0x10],ax
  225ad0:   48 8d 7d e8             lea    rdi,[rbp-0x18]
  225ad4:   e8 e7 5c 00 00          call   22b7c0 <std.debug.print.103>
  225ad9:   48 83 c4 20             add    rsp,0x20
  225add:   5d                      pop    rbp
  225ade:   c3                      ret
  225adf:   90                      nop
Enter fullscreen mode Exit fullscreen mode

0x2038ea points to the address where our string is stored in the ELF

2038e0 29004861 69207468 65726500 64776172  ).Hai there.dwar
2038f0 663a2075 6e68616e 646c6564 20666f72  f: unhandled for
Enter fullscreen mode Exit fullscreen mode

We first make 32 bytes of space on the stack (sub rsp 0x20) and then copy the string literal starting at address 0xa to 0x2 using 2 instructions ("Hai There" is 9 bytes, so we copy 8 bytes using the first instruction and then the last byte using another)
We then copy the string into the stack from rbp-0x18 to rbp-0x10 and call debug.print with the base address to our copy (rbp-0x18)

Discussion (0)