程序计数器,IA32指令集中通常称为PC,用%eip表示,指示即将执行的下一条指令在存储器中的地址。
int accum = 0;
int sum(int x, int y)
{
int t = x + y;
accum += t;
return t;
}
int p(int x)
{
return sum(x,x);
}
gcc -O1 -S -m32 code.c
-O1表示使用1级优化。
-S表示生成汇编代码。
-m32,表示生成32位的汇编代码。
汇编代码中包含下面几行:
sum:
pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %eax
addl 8(%ebp), %eax
addl %eax, accum
popl %ebp
ret
gcc -O1 -c -m32 code.c
gdb code.o
x /17xb sum
0x0 <sum>: 0x55 0x89 0xe5 0x8b 0x45 0x0c 0x03 0x45
0x8 <sum+8>: 0x08 0x01 0x05 0x00 0x00 0x00 0x00 0x5d
0x10 <sum+16>: 0xc3
objdump -d code.o
00000000 <sum>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 03 45 08 add 0x8(%ebp),%eax
9: 01 05 00 00 00 00 add %eax,0x0
f: 5d pop %ebp
10: c3 ret
再看一个例子:
int simple(int *xp, int y)
{
intt = *xp + y;
*xp= t;
return t;
}
simple.s文件的内容如下:
.file "simple.c"
.text
.globl simple
.type simple, @function
simple:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %eax
addl (%edx), %eax
movl %eax, (%edx)
popl %ebp
ret
.size simple, .-simple
.ident "GCC: (GNU) 4.1.2 20080704 (Red Hat4.1.2-44)"
.section .note.GNU-stack,"",@progbits
所有以“.”开头的行都是指导汇编器和链接器的命令,我们通常可以忽略这些行。
汇编指令的格式是AT&T格式的,gcc可以产生simple函数的intel格式的代码。
gcc -O1 -S -m32 -masm=intel simple.c
simple:
push %ebp
mov %ebp, %esp
mov %edx, DWORD PTR [%ebp+8]
mov %eax, DWORD PTR [%ebp+12]
add %eax, DWORD PTR [%edx]
mov DWORD PTR [%edx], %eax
pop %ebp
ret