C++源代码:
#include<stdio.h> int main(int argc,char *argv[]) { int array[5]={1,2,3,4,5}; printf("%d\n",array[1]); printf("%d\n",array[argc]); return 0; }
Dump of assembler code for function main: 0x004012f0 <main+0>: push %ebp 0x004012f1 <main+1>: mov %esp,%ebp 0x004012f3 <main+3>: sub $0x48,%esp 0x004012f6 <main+6>: and $0xfffffff0,%esp 0x004012f9 <main+9>: mov $0x0,%eax 0x004012fe <main+14>: add $0xf,%eax 0x00401301 <main+17>: add $0xf,%eax 0x00401304 <main+20>: shr $0x4,%eax 0x00401307 <main+23>: shl $0x4,%eax 0x0040130a <main+26>: mov %eax,-0x2c(%ebp) 0x0040130d <main+29>: mov -0x2c(%ebp),%eax 0x00401310 <main+32>: call 0x401880 <_alloca> 0x00401315 <main+37>: call 0x401400 <__main> 0x0040131a <main+42>: movl $0x1,-0x28(%ebp) 0x00401321 <main+49>: movl $0x2,-0x24(%ebp) 0x00401328 <main+56>: movl $0x3,-0x20(%ebp) 0x0040132f <main+63>: movl $0x4,-0x1c(%ebp) 0x00401336 <main+70>: movl $0x5,-0x18(%ebp) 0x0040133d <main+77>: mov -0x24(%ebp),%eax 0x00401340 <main+80>: mov %eax,0x4(%esp) 0x00401344 <main+84>: movl $0x403000,(%esp) 0x0040134b <main+91>: call 0x4018e0 <printf> 0x00401350 <main+96>: mov 0x8(%ebp),%eax 0x00401353 <main+99>: mov -0x28(%ebp,%eax,4),%eax 0x00401357 <main+103>: mov %eax,0x4(%esp) 0x0040135b <main+107>: movl $0x403000,(%esp) 0x00401362 <main+114>: call 0x4018e0 <printf> 0x00401367 <main+119>: mov $0x0,%eax 0x0040136c <main+124>: leave 0x0040136d <main+125>: ret End of assembler dump. (gdb)在下标值为常量的情况下,由于类型大小为已知数,编译器可以直接计算出数据所在的地址,其寻址过程和局部变量相同:
mov -0x24(%ebp),%eax在下标值为变量的情况下,编译器无法计算出对应的地址,只能先进行地址偏移计算,然后再得出目标数据所在的地址:
mov 0x8(%ebp),%eax mov -0x28(%ebp,%eax,4),%eax
0x8(%ebp)即为argc的值。
Intel语法的间接内存引用的格式为:
section:[base+index*scale+displacement]
而在AT&T语法中对应的形式为:
section:displacement(base,index,scale)