mar*_*tin 5 c x86 assembly gcc
最近,我正在研究#define,const和enum的汇编代码:
C代码(#define):
3 #define pi 3
4 int main(void)
5 {
6 int a,r=1;
7 a=2*pi*r;
8 return 0;
9 }
Run Code Online (Sandbox Code Playgroud)
GCC生成的汇编代码(用于C代码中的第6行和第7行):
6 mov $0x1, -0x4(%ebp)
7 mov -0x4(%ebp), %edx
7 mov %edx, %eax
7 add %eax, %eax
7 add %edx, %eax
7 add %eax, %eax
7 mov %eax, -0x8(%ebp)
Run Code Online (Sandbox Code Playgroud)
C代码(枚举):
2 int main(void)
3 {
4 int a,r=1;
5 enum{pi=3};
6 a=2*pi*r;
7 return 0;
8 }
Run Code Online (Sandbox Code Playgroud)
GCC生成的汇编代码(用于c代码中的第4行和第6行):
6 mov $0x1, -0x4(%ebp)
7 mov -0x4(%ebp), %edx
7 mov %edx, %eax
7 add %eax, %eax
7 add %edx, %eax
7 add %eax, %eax
7 mov %eax, -0x8(%ebp)
Run Code Online (Sandbox Code Playgroud)
C代码(常量):
4 int main(void)
5 {
6 int a,r=1;
7 const int pi=3;
8 a=2*pi*r;
9 return 0;
10 }
Run Code Online (Sandbox Code Playgroud)
GCC生成的汇编代码(用于c代码中的第7行和第8行):
6 movl $0x3, -0x8(%ebp)
7 movl $0x3, -0x4(%ebp)
8 mov -0x4(%ebp), %eax
8 add %eax, %eax
8 imul -0x8(%ebp), %eax
8 mov %eax, 0xc(%ebp)
Run Code Online (Sandbox Code Playgroud)
我发现使用#define和enum汇编代码是一样的.编译器使用3个添加指令来执行乘法.但是,在使用时,使用constimul指令.谁知道背后的原因?
不同之处在于,#define或者enum值3不需要作为代码中的显式值存在,因此编译器决定使用两个添加指令而不是为常量3分配空间.add reg,reg指令是每个指令2个字节,所以6个字节的指令和0个字节的常数乘以3,这比imul使用4个字节的常数更小.再加上使用添加指令的方式,它可以实现*2*3的非常直译,因此这可能不是大小优化,只要乘以2或3,它就可以是默认的编译器输出.通常是比乘法更快的指令).
#define并且enum不声明实例,它们只提供了为值3赋予符号名称的方法,因此编译器可以选择制作更小的代码.
mov $0x1, -0x4(%ebp) ; r=1
mov -0x4(%ebp), %edx ; edx = r
mov %edx, %eax ; eax = edx
add %eax, %eax ; *2
add %edx, %eax ;
add %eax, %eax ; *3
mov %eax, -0x8(%ebp) ; a = eax
Run Code Online (Sandbox Code Playgroud)
但是当你声明时const int pi = 3,你告诉编译器为整数值分配空间并用3初始化它.它使用4个字节,但是该常量现在可用作imul指令的操作数.
movl $0x3, -0x8(%ebp) ; pi = 3
movl $0x3, -0x4(%ebp) ; r = 3? (typo?)
mov -0x4(%ebp), %eax ; eax = r
add %eax, %eax ; *2
imul -0x8(%ebp), %eax ; *pi
mov %eax, 0xc(%ebp) ; a = eax
Run Code Online (Sandbox Code Playgroud)
顺便说一下,这显然不是优化代码.因为a从未使用过该值,所以如果打开优化,编译器就会执行
xor eax, eax ; return 0
Run Code Online (Sandbox Code Playgroud)
在所有3个案例中.
我尝试使用MSVC,在调试模式下,我得到所有3种情况的相同输出,MSVC总是使用imul的文字6.即使在情况3时,它创建const int = 3它实际上并没有在imul中引用它.
我不认为这个测试真的告诉你有关const vs define vs enum的任何信息,因为这是非优化代码.
| 归档时间: |
|
| 查看次数: |
2007 次 |
| 最近记录: |