学习C++反汇编-下标分别为常量和变量的寻址

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)

你可能感兴趣的:(学习C++反汇编-下标分别为常量和变量的寻址)