I can not understand the assembler code resulting from the compilation of the simplest program:

int main(int argc, char* argv[]) { char str[] = "Hello, world!\n"; } 

When using gcc6.3 x86_64 , the result is:

 main: pushq %rbp movq %rsp, %rbp movl %edi, -20(%rbp) movq %rsi, -32(%rbp) movabsq $8583909746840200520, %rax movq %rax, -16(%rbp) movl $1684828783, -8(%rbp) movw $2593, -4(%rbp) movb $0, -2(%rbp) movl $0, %eax popq %rbp ret 

Where $8583909746840200520 ?

I note that if you write this:

 int main(int argc, char* argv[]) { char str[] = "Hello, world!\0"; } 

it turns out quite different:

 .LC0: .string "Hello, world!" .string "" main: pushq %rbp movq %rsp, %rbp movl %edi, -20(%rbp) movq %rsi, -32(%rbp) movq .LC0(%rip), %rax movq %rax, -16(%rbp) movl .LC0+8(%rip), %eax movl %eax, -8(%rbp) movzwl .LC0+12(%rip), %eax movw %ax, -4(%rbp) movzbl .LC0+14(%rip), %eax movb %al, -2(%rbp) movl $0, %eax popq %rbp ret 
  • And what confuses in the second case? The compiler is free to choose how to initialize variables. - PinkTux
  • @PinkTux, I don’t understand the fundamental difference between the end of a line at \ 0 or \ n from the compiler's point of view - xperious
  • It is possible (only a hypothesis) that the explicit 0 inside the quotation marks makes the data be perceived not as a "string string", but as an array, hence the various methods. But you still need to understand with what optimization all this is compiled. - PinkTux
  • In the first case, str formally a string. In the second - is not formally. It is clear that this difference is not a reason for the difference in such "doing nothing" code, but nonetheless. Yes, and there is a suspicion that the code was compiled without optimizations, which makes the question of the difference meaningless. - AnT
  • @Ant, yes, without optimizations ... I’m learning about asm ... of course without optimizations, otherwise the devil will break my leg, nothing becomes clear - xperious

1 answer 1

8583909746840200520 (dec) == 77202C6F6C6C6548 (hex) == "w, olleH" (str), the second giant number is the remainder of the string.

  • Even I can not enter as you converted a string into a number - xperious
  • @xperious Hiew - select - Shift-F8-hex2bin, but you don’t have it, so asciitable.com and see: 0x77 - 'w' and so on ... - Vladimir Martyanov
  • 3
    @Abyx: easier: 8583909746840200520 .to_bytes(8, 'little') . Convert binary to ASCII and vice versa - jfs
  • one
    @xperious because your platform is little-endian, then the bytes among you go from low to high. But every byte is the binary representation of the character, aka hex, aka ASCII code, in this case. With widechar or Unicode will be more fun, there hexadecimal values ​​(identifiers) of characters do NOT coincide with the binary representation. - Swift
  • one
    77202C6F6C6C6548 (hex) = "Hello, w" in little endian, in memory the order of bytes is different than in the record. - Swift