关于网友提出的“ ◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆”问题疑问,本网通过在网上对“ ◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: ◆◆◆精通汇编的老大请入,请教几个内嵌汇编的问题◆◆◆
描述: 这几个函数都来自于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