I write three similar demos and compile them with   gcc -S 1.c -o 1.s 
these demos diff in one line :
 //  1.c , get 1.s
1 #include <stdio.h>
2 int main()
3 {
4    int a[2]={111,222};
5    int j=0;
6    printf("%d ",0[a]);  // another two are a[j] and j[a]
7    return 0;
8 }
I use vimdiff to view assemble demo
in .s files, a[j] and j[a] is the same.
there are three different line in 0[a]
; main in 0[a] , file 1.s
.loc 1 5 0
movl    $111, -16(%rbp)
movl    $222, -12(%rbp)
.loc 1 6 0
movl    $0, -20(%rbp)
.loc 1 7 0                            
movl    -20(%rbp), %eax              | no these two line  
cltq                                 | in a[j] and j[a]
movl    -16(%rbp,%rax,4), %eax       
movl    %eax, %esi
movl    $.LC0, %edi
movl    $0, %eax
call    printf 
I learn 8086 and intel assemble last year, several days ago find AT&T and feel a little strange. In 1.s ,ctlq extend rax to 64bit , and $0 doesn't need that. Is that right?
The problem is , after compiled to .s file, a[j] and j[a] is the same,does gcc compiler recognize the base address(pointer a) and the offset (j) ? a and j are both in memory,how can gcc get eax and ebp? Check their type?
 
    