您好,欢迎来到[编程问答]网站首页   源码下载   电子书籍   软件下载   专题
当前位置:首页 >> 编程问答 >> Delphi >> ◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆

◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆

来源:网络整理     时间:2016/7/12 5:57:41     关键词:

关于网友提出的“ ◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆”问题疑问,本网通过在网上对“ ◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:

问题: ◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆
描述:

这几个函数都来自于VCL。
*********
* 问题1 *
*********
function CompareStr(const S1, S2: string): Integer; assembler;
asm
        PUSH    ESI
        PUSH    EDI
        
        MOV     ESI,EAX 
        MOV     EDI,EDX
        
        OR      EAX,EAX
        JE      @@1
        MOV     EAX,[EAX-4]
        
@@1:    OR      EDX,EDX
        JE      @@2
        MOV     EDX,[EDX-4]
        
@@2:    MOV     ECX,EAX
        CMP     ECX,EDX
        JBE     @@3
        MOV     ECX,EDX
        
@@3:    CMP     ECX,ECX //是否是为了对齐?
        REPE    CMPSB
        JE      @@4
        MOVZX   EAX,BYTE PTR [ESI-1]
        MOVZX   EDX,BYTE PTR [EDI-1]
        
@@4:    SUB     EAX,EDX
        POP     EDI
        POP     ESI
end;
///////////////////////////////////////////////////////////////
function CompareText(const S1, S2: string): Integer; assembler;
asm
        PUSH    ESI
        PUSH    EDI
        PUSH    EBX
        
        MOV     ESI,EAX
        MOV     EDI,EDX
        
        OR      EAX,EAX
        JE      @@0
        MOV     EAX,[EAX-4]
@@0:    OR      EDX,EDX
        JE      @@1
        MOV     EDX,[EDX-4]
        
@@1:    MOV     ECX,EAX
        CMP     ECX,EDX 
        JBE     @@2
        MOV     ECX,EDX
        
@@2:    CMP     ECX,ECX //是否是为了对齐?
@@3:    REPE    CMPSB
        JE      @@6 
        
        MOV     BL,BYTE PTR [ESI-1]
        CMP     BL,'a'              
        JB      @@4
        CMP     BL,'z'
        JA      @@4
        SUB     BL,20H
        
@@4:    MOV     BH,BYTE PTR [EDI-1]
        CMP     BH,'a'
        JB      @@5
        CMP     BH,'z'
        JA      @@5
        SUB     BH,20H
        
@@5:    CMP     BL,BH
        JE      @@3
        MOVZX   EAX,BL
        MOVZX   EDX,BH
        
@@6:    SUB     EAX,EDX
        POP     EBX
        POP     EDI
        POP     ESI
end;
请问上面两个函数中的 CMP ECX, ECX存在的目的是否都是为了对齐?我把他们注释掉也可以正常运行。
我查到数据是:
CMP                      Clocks                 Size
Operands         808x  286   386   486          Bytes
reg,reg           3     2     2     1             2
mem,reg          9+EA   7     5     2            2-4  (W88=13+EA)
reg,mem          9+EA   6     6     2            2-4  (W88=13+EA)
reg,immed         4     3     2     1            3-4
mem,immed       10+EA   6     5     2            3-6  (W88=14+EA)
accum,immed       4     3     2     1            2-3
如果是,请问为什么用CMP,好处是什么?
*********
* 问题2 *
*********
function StrLen(const Str: PChar): Cardinal; assembler;
asm
        MOV     EDX,EDI
        MOV     EDI,EAX
        
        MOV     ECX,0FFFFFFFFH //ECX = -1
        XOR     AL,AL          //AL = 0
        REPNE   SCASB          //把AL的内容与EDI作比较, 为0则字符串终止
        MOV     EAX,0FFFFFFFEH //EAX = -1
        SUB     EAX,ECX        // -1 - ECX,返回值为负吗?
        
        MOV     EDI,EDX
end;
难道返回值为负数吗?
*********
* 问题3 *
*********
function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;
asm
        PUSH    ESI
        PUSH    EDI
        
        MOV     ESI,P1
        MOV     EDI,P2
        
        MOV     EDX,ECX
        
        XOR     EAX,EAX //清0
        
        AND     EDX,3   //???
        
        SHR     ECX,1   //循环计数除以4
        SHR     ECX,1
        
        REPE    CMPSD   //循环比较双字
        JNE     @@2     //不等于则返回False
        
        MOV     ECX,EDX //等于则继续
        
        REPE    CMPSB   //循环比较单字
        JNE     @@2     //不等于则返回False
        
@@1:    INC     EAX     //都等于返回True
@@2:    POP     EDI
        POP     ESI
end;
问题:AND EDX,3 有什么作用?取 EDX mod 4吗?
请得道高人赐教,谢谢。


解决方案1:

>>1 这段程序写的很差,
>>CMP ECX, ECX ;是没有用的,但是影响标志位,下面的JE会用到,但
没用?REPE    CMPSB这一句不用ZF吗?高人来了
>>2 SUB是无符号的减法
intel x86的加减法有符号问题吗?如果有,那也是有符号的

解决方案2:


1 这段程序写的很差,
CMP ECX, ECX ;是没有用的,但是影响标志位,下面的JE会用到,但

解决方案3:

高位都是0
低位与0011 and操作自然是对4求余了。

解决方案4:

当然有用,你举的例子不够特殊
CompareStr1('Test','')
再去掉CMP ECX, ECX试试?这时候因为一个字符串为空,ECX为0,循环次数为0,CMPSB不会改变ZF,这时候如果ZF=0,就会导致执行后面的MOVZX   EDX,BYTE PTR [EDI-1]执行,这也必然导致异常.于是这时候就必须使用CMP ECX, ECX将ZF置为1
但你问的是StrLen中的SUB,不是CompareStr中的,CompareStr当然会出现负数,不看代码,帮助也说的很明白了

解决方案5:

刚才看帖子
http://www.tianyaclub.com/New/TechForum/Content.asp?idArticle=542110&idItem=20
去了
问题1
我对汇编和IA32架构相关的东西没有深入的研究,呵呵
CMP ECX,ECX //是否是为了对齐?
我猜是为了让ZF=1吧
CMP就是不影响通用寄存器的SUB,如TEST是不影响通用寄存器的AND一样
问题2
你不要把0FFFFFFFFH 当作-1来看,当作无符号整数


以上介绍了“ ◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/2540138.html

相关图片

相关文章