• 全部
  • 问答

等同指令问题?

atm2001 2002-02-10 10:36:50
最近我的组员经常问我类似下面的问题
“ENTER 8,0

PUSH EBP
MOV EBP,ESP
SUB ESP,8
是功能相同的指令,他们的执行速度为什么不同
还有


0040601A E807000000 call 00406026h
0040601F 34F4 xor al,F4
00406021 F0A4 lock movsb
00406023 288C085EB934AC sub [eax+ecx-53CB46A2],cl
0040602A 0200 add al,[eax]

0040601A E800000000 call 0040601F
0040601F 5E pop si
的功能也是相同,但前者的执行速度明显比后者快,为什么呢?”

在下虽然知道一些,但不是太了解(不能让我的组员满意),请教高手

...全文
12 点赞 收藏 13
写回复
13 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
awinder 2002-02-14
Assembly/Compiler Coding Rule 39. (ML impact, M generality) Avoid using complex instructions (for example, enter, leave, or loop) that generally have more than four µops and require multiple cycles to decode. Use sequences of simple instructions instead.
从这条规则来看,enter属于复杂指令,并需要多条微指令和循环,故时间耗费长一些。因为详细的微指令结构Intel没有公开,也不可能详细研究了。
这是enter指令的执行次序:
PUSH EBP;
FRAME_PTR ←ESP;
IF LEVEL > 0
THEN
DO (LEVEL −1) times
EBP ←EBP −4;
PUSH Pointer(EBP); (* doubleword pointed to by EBP *)
OD;
PUSH FRAME_PTR;
FI;
EBP ←FRAME_PTR;
ESP ←ESP −STORAGE;
从enter指令的执行次序分析,由于需要嵌套使用,要判断level所以需要一个循环,故微指令要多一些。

至于第二个例子,第一种写法只不过在call和pop之间插入了其它指令,可能便于并发执行,具体原因还不清楚。
回复
atm2001 2002-02-14
wylpro兄弟:
第二个例子是病毒编程中常见的一段代码。。。。
回复
wylpro 2002-02-14
第一个例子中我没看过时钟表,但如果说 enter XX 更慢一些也是可能的,
你查一下周期表就知道了很多不常用的指令都消耗很多的周期,这是因为其它长用指令intel都做了优化(全部用硬连线)当然快,而CISC(复杂)指令都是要经过微代码转换控制等一系列过程(其实是转换成的微代码多)所以很慢,
另外,想说一下 在汇编中没有什么 直观或结构化 的编程思想,唯一的规则就是没有规则,要想直观,用C 就行了,汇编本来就是机器相关的,不需要、直观。
至于第二个例子,我还没看懂是在做什么。
不过至于时钟周期计算,远比这复杂(想象不到的)根本不是只计算指令周期消耗就行的,比如说,同样一个 MOV byte ptr [xxxx],ax 如果这个地址(XXXX)是可缓存的肯定要快,而要访问内存就慢一些,如果是显存访问,周期差距可以上百倍。总之实际限制非常复杂,往往是根本想不到的地方限制了速度,不过好在一般编程人员不会涉及到这种分秒必争的地步。
回复
Chice_wxg 2002-02-13
第二个问题好象与奔腾流水线有关。

前者指令可以并发执行。
回复
snowingedge 2002-02-12
不过从enter指令中也可以看出一些CISC体系的设计思想:把复杂性从软件移到硬件。不过P4中,应该看不到这种指令了。
回复
snowingedge 2002-02-12
先看一下pop指令都作了些什么:

Operation
IF StackAddrSize ← 32
THEN
IF OperandSize ← 32
THEN
DEST ← SS:ESP; (* copy a doubleword *)
ESP ← ESP + 4;
ELSE (* OperandSize ← 16*)
DEST ← SS:ESP; (* copy a word *)
ESP ← ESP + 2;
FI;
ELSE (* StackAddrSize ← 16* )
IF OperandSize ← 16
THEN
DEST ← SS:SP; (* copy a word *)
SP ← SP + 2;
ELSE (* OperandSize ← 32 *)
DEST ← SS:SP; (* copy a doubleword *)
SP ← SP + 4;
FI;
FI;

再看看leave:

Operation
IF StackAddressSize ← 32
THEN
ESP ← EBP;
ELSE (* StackAddressSize ← 16*)
SP ← BP;
FI;
IF OperandSize ← 32
THEN
EBP ← Pop();
ELSE (* OperandSize ← 16*)
BP ← Pop();
FI;

可以看出来,leave指令本身还要再执行一个pop,我想这是不是leave比较慢的原因呢?(enter也类似)
回复
vBin 2002-02-12
呵呵,我记错啦。
不好意思,最近很少动汇编,这方面的东西有点丢呀。

赶快回家补去......否则要落伍喽...........
回复
snowingedge 2002-02-12
是否和指令的微指令解码有关呢??
回复
atm2001 2002-02-11
还是Awinder的水平高些,在下查过intel的资料,上面讲得很很模糊,
根本看不出什么。。。。。
回复
awinder 2002-02-10
vBin(彬) :
enter 应该是一条指令,而不是宏。机器码是c8,我也不清楚它为什么这么慢(pentium上要11个周期)。我再查一下intel的资料吧。
回复
vBin 2002-02-10
我没试过,也没看过这方面的资料.
但我同意楼上的观点,
毕竟
PUSH EBP
MOV EBP,ESP
SUB ESP,8
是一个非常直观的代码.


ENTER 8,0
毕竟一个宏,虽然调用起来只是一句
但是实际操作,应该比上面那个慢些.
回复
awinder 2002-02-10
PUSH EBP
MOV EBP,ESP
SUB ESP,8
要快很多,但是enter,leave更直观些,尤其是嵌套使用的时候。
masm32v7中的帮助文件中列举了很多功能相同的指令,并给出了最优指令。
回复
cnss 2002-02-10
学习!

PS:第一个例子里是哪个更快些??
回复
相关推荐
发帖
汇编语言
创建于2007-08-27

2.0w+

社区成员

汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
申请成为版主
帖子事件
创建了帖子
2002-02-10 10:36
社区公告
暂无公告