关于一个加法优化的一个地方.....
2011-07-24 23:18
232 查看
#include <stdlib.h>
#include <stdio.h>
#include "Base.h"
int main(int argc, char* argv[], char* envp[])
{
int nNum;
int nA = 12;
nNum = argc + nA;
printf("%d\r\n", nNum);
nNum = argc + 9;
printf("%d\r\n", nNum);
nNum = nNum + 1;
printf("%d\r\n", nNum);
return 0;
}
下面是汇编:
01291000 >/$ 55 PUSH EBP
01291001 |. 8BEC MOV EBP,ESP
01291003 |. 56 PUSH ESI
01291004 |. 8B35 A0202901 MOV ESI,DWORD PTR DS:[<&MSVCR100.printf>>; MSVCR100.printf
0129100A |. 57 PUSH EDI
0129100B |. 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ; EDI的值变为1
0129100E |. 8D47 0C LEA EAX,DWORD PTR DS:[EDI+C] ; EAX的值变为9
01291011 |. 50 PUSH EAX ; /<%d>
01291012 |. 68 F4202901 PUSH OFFSET Bug_C++.??_C@_04HGIPLDBL@?$C>; |format = "%d
"
01291017 |. FFD6 CALL ESI ; \printf
01291019 |. 83C7 09 ADD EDI,9
0129101C |. 57 PUSH EDI
0129101D |. 68 F4202901 PUSH OFFSET Bug_C++.??_C@_04HGIPLDBL@?$C>; ASCII "%d
"
01291022 |. FFD6 CALL ESI
01291024 |. 47 INC EDI
01291025 |. 57 PUSH EDI
01291026 |. 68 F4202901 PUSH OFFSET Bug_C++.??_C@_04HGIPLDBL@?$C>; ASCII "%d
"
0129102B |. FFD6 CALL ESI
0129102D |. 83C4 18 ADD ESP,18
01291030 |. 5F POP EDI
01291031 |. 33C0 XOR EAX,EAX
01291033 |. 5E POP ESI
01291034 |. 5D POP EBP
01291035 \. C3 RETN
0129100B |. 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ; EDI的值变为1
0129100E |. 8D47 0C LEA EAX,DWORD PTR DS:[EDI+C] ; EAX的值变为9
mov edi, dword ptr ss:[ebp + 8]
把内存单元中的内容送入edi
lea eax, dword ptr ds:[edi + c]
这里之所以要用lea是因为lea载入的是相对偏移地址...就是edi + c的结果..
如果用add做
mov eax, 8(或者在内存中取)
add eax, edi
因为两个数不可能是立即数...所以只能从内存中拿...如果用mov 则一共需要3条指令
mov eax, 9
mov edi, xxxx
add eax, edi
但是用lea就可以将指令缩短为2条..因为它支持3个OP的操作...
lea eax, dword ptr ds:[edi + 9]
这样无形中节约了一条指令..
#include <stdio.h>
#include "Base.h"
int main(int argc, char* argv[], char* envp[])
{
int nNum;
int nA = 12;
nNum = argc + nA;
printf("%d\r\n", nNum);
nNum = argc + 9;
printf("%d\r\n", nNum);
nNum = nNum + 1;
printf("%d\r\n", nNum);
return 0;
}
下面是汇编:
01291000 >/$ 55 PUSH EBP
01291001 |. 8BEC MOV EBP,ESP
01291003 |. 56 PUSH ESI
01291004 |. 8B35 A0202901 MOV ESI,DWORD PTR DS:[<&MSVCR100.printf>>; MSVCR100.printf
0129100A |. 57 PUSH EDI
0129100B |. 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ; EDI的值变为1
0129100E |. 8D47 0C LEA EAX,DWORD PTR DS:[EDI+C] ; EAX的值变为9
01291011 |. 50 PUSH EAX ; /<%d>
01291012 |. 68 F4202901 PUSH OFFSET Bug_C++.??_C@_04HGIPLDBL@?$C>; |format = "%d
"
01291017 |. FFD6 CALL ESI ; \printf
01291019 |. 83C7 09 ADD EDI,9
0129101C |. 57 PUSH EDI
0129101D |. 68 F4202901 PUSH OFFSET Bug_C++.??_C@_04HGIPLDBL@?$C>; ASCII "%d
"
01291022 |. FFD6 CALL ESI
01291024 |. 47 INC EDI
01291025 |. 57 PUSH EDI
01291026 |. 68 F4202901 PUSH OFFSET Bug_C++.??_C@_04HGIPLDBL@?$C>; ASCII "%d
"
0129102B |. FFD6 CALL ESI
0129102D |. 83C4 18 ADD ESP,18
01291030 |. 5F POP EDI
01291031 |. 33C0 XOR EAX,EAX
01291033 |. 5E POP ESI
01291034 |. 5D POP EBP
01291035 \. C3 RETN
0129100B |. 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ; EDI的值变为1
0129100E |. 8D47 0C LEA EAX,DWORD PTR DS:[EDI+C] ; EAX的值变为9
mov edi, dword ptr ss:[ebp + 8]
把内存单元中的内容送入edi
lea eax, dword ptr ds:[edi + c]
这里之所以要用lea是因为lea载入的是相对偏移地址...就是edi + c的结果..
如果用add做
mov eax, 8(或者在内存中取)
add eax, edi
因为两个数不可能是立即数...所以只能从内存中拿...如果用mov 则一共需要3条指令
mov eax, 9
mov edi, xxxx
add eax, edi
但是用lea就可以将指令缩短为2条..因为它支持3个OP的操作...
lea eax, dword ptr ds:[edi + 9]
这样无形中节约了一条指令..
相关文章推荐
- 关于Qt中QMap的一个需要注意的地方
- 关于开一个网络(软件)公司办公地方的选取
- 一个关于js 优化的问题
- 【安卓-自定义布局】安卓App开发思路 一步一个脚印(十三)关于ListView的优化总结
- 设计一个日期类Date,,要求: (1)包含年(year)、月(month)和日(day)私有数据成员。 (2)包含构造函数,重载关于一日期加上天数的加法运算符+、重载关于一日期减去天数的减加运算符-
- 关于oracle sql优化的一个容易忽略的问题。
- 关于需要互斥的地方的一个好东西(智能锁)
- 关于相对布局中控件摆放位置的一个需要注意的小地方
- 关于不需用使用top的地方,而必须使用的一个小问题
- *关于Js中this值得注意的一个地方
- 关于DataAdapter去Update一个DataTable的优化
- 转一个关于优化sql的文章
- 一个关于优化SQL的文章
- 转一个关于优化SQL的文章
- 记录一个关于互联网、网页设计、Web开发、服务器运维优化、项目管理、网站运营、网站安全的网站
- 关于上一个sql优化测试的部分知识
- 关于C++语法的一个容易出错的地方。
- 一个初学者关于vr游戏开发的优化总结
- 一个关于防止编译器优化特定代码的问题
- 一个关于从1到100的加法算法