0

I have written a small array program in c

#include <stdio.h>
int main()
{
    int arr[]={1,2,3,4,5};//int size is 4, elements 5 so size of array = 4*5 = 20
    printf("%d\n", sizeof(arr));
    return 0;
}

I compiled this with

gcc -O2 -fverbose-asm -S -c arr_n_pointer_confusion.c 

I got this,

    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%d\n"
    .section    .text.startup,"ax",@progbits
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB22:
    .cfi_startproc
    pushl   %ebp    #
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp  #,
    .cfi_def_cfa_register 5
    andl    $-16, %esp  #,
    subl    $16, %esp   #,
    movl    $20, 8(%esp)    #,
    movl    $.LC0, 4(%esp)  #,
    movl    $1, (%esp)  #,
    call    __printf_chk    #
    xorl    %eax, %eax  #
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE22:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
    .section    .note.GNU-stack,"",@progbits

Can anybody relate the steps in assembly from C. Why I am trying to do this is to understand a little the assembly code so that I can understand the difference from pointer to array.

nikhil chaubey
  • 369
  • 1
  • 5
  • 11
  • What's the question? The size of the array is 20, as you've figured out, and so has the compiler. So it prints 20. No instructions are executed to arrive at this number. – Kerrek SB Jan 24 '16 at 18:40
  • I have a persistent confusion in strings, array and pointers. Thats why I want to learn assembly of gcc. Once I know usual assembly code that is generated, i can understand the difference myself. – nikhil chaubey Jan 24 '16 at 18:42
  • You should fix your C before you dive into machine code. The type of a `sizeof` expression is `size_t`, which needs to be formatted with `%zu`. Passing it to `%d` results in undefined behaviour. – Kerrek SB Jan 24 '16 at 18:46
  • [Machine code resulting from optimized build](https://goo.gl/erhjP1) – Kerrek SB Jan 24 '16 at 18:46
  • @KerrekSB I used -Wall too, didn't saw any warning. – nikhil chaubey Jan 24 '16 at 18:48
  • `printf("%d\n", sizeof(arr));` invokes UB. [`sizeof` must be printed using `%zu`](https://stackoverflow.com/q/940087/995714) – phuclv Jan 30 '19 at 02:05

2 Answers2

1

Basically, because the compiler knows the contents of the array at compile-time, it can remove the array, and just replace sizeof(array) with 20, without having to actually initialize the array at runtime.

.cfi_startproc
pushl   %ebp    # Save the value of ebp (points to the base of the stack) in the stack
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl    %esp, %ebp  #, Set the value of the base of the stack to the top of it
.cfi_def_cfa_register 5
andl    $-16, %esp  # Align the stack with a 16-byte boundary, used for SIMD instructions
subl    $16, %esp   # Subtract 16 from the value of the stack pointer (reserving 16 bytes of space for the stack)
movl    $20, 8(%esp)    # Set the memory 8 bytes above the stack as '20'
movl    $.LC0, 4(%esp)  # Move the string "%d\n" 4 bytes above the stack
movl    $1, (%esp)  # Set the flag for __printf_chk() to 1, enabling stack overflow checks
call    __printf_chk    # Print our string
xorl    %eax, %eax # Zero out the eax register (i.e. store the return code in eax, which is 0)

. So the parameters passed to __printf_chk are (1, "%d\n", 20).

Mitsos101
  • 551
  • 3
  • 15
0

Compile with gcc -g -fverbose-asm -S arr_n_pointer_confusion.c. The compiler then adds .loc pseudo statements which refer to the line numbers in the source file. You can then easily relate the assembler source to the C code.

Bernhard
  • 354
  • 1
  • 6