为什么会出错,有关汇编的(200分)

  • 主题发起人 主题发起人 xzfxzf
  • 开始时间 开始时间
X

xzfxzf

Unregistered / Unconfirmed
GUEST, unregistred user!
function FindName(SearchStr,NameStr:string):boolean
assembler;
{
Compare SearchStr with NameStr, and allow wildcards in SearchStr.
The following wildcards are allowed:
*ABC* matches everything which contains ABC
[A-C]* matches everything that starts with either A,B or C
[ADEF-JW-Z] matches A,D,E,F,G,H,I,J,W,V,X,Y or Z
ABC? matches ABC, ABC1, ABC2, ABCA, ABCB etc.
ABC[?] matches ABC1, ABC2, ABCA, ABCB etc. (but not ABC)
ABC* matches everything starting with ABC
(for using with DOS filenames like DOS (and 4DOS), you must split the
filename in the extention and the filename, and compare them seperately)
}

var
LastW:word;
asm
cld
push ds
lds si,SearchStr
les di,NameStr
xor ah,ah
lodsb
mov cx,ax
mov al,es:[di]
inc di
mov bx,ax
or cx,cx
jnz @ChkChr
or bx,bx
jz @ChrAOk
jmp @ChrNOk
xor dh,dh
@ChkChr:
lodsb
cmp al,'*'
jne @ChkQues
dec cx
jz @ChrAOk
mov dh,1
mov LastW,cx
jmp @ChkChr
@ChkQues:
cmp al,'?'
jnz @NormChr
inc di
or bx,bx
je @ChrOk
dec bx
jmp @ChrOk
@NormChr:
or bx,bx
je @ChrNOk
{From here to @No4DosChr is used for [0-9]/[?]/[!0-9] 4DOS wildcards...}
cmp al,'['
jne @No4DosChr
cmp word ptr [si],']?'
je @SkipRange
mov ah,byte ptr es:[di]
xor dl,dl
cmp byte ptr [si],'!'
jnz @ChkRange
inc si
dec cx
jz @ChrNOk
inc dx
@ChkRange:
lodsb
dec cx
jz @ChrNOk
cmp al,']'
je @NChrNOk
cmp ah,al
je @NChrOk
cmp byte ptr [si],'-'
jne @ChkRange
inc si
dec cx
jz @ChrNOk
cmp ah,al
jae @ChkR2
inc si {Throw a-Z < away}
dec cx
jz @ChrNOk
jmp @ChkRange
@ChkR2:
lodsb
dec cx
jz @ChrNOk
cmp ah,al
ja @ChkRange {= jbe @NChrOk
jmp @ChkRange}
@NChrOk:
or dl,dl
jnz @ChrNOk
inc dx
@NChrNOk:
or dl,dl
jz @ChrNOk
@NNChrOk:
cmp al,']'
je @NNNChrOk
@SkipRange:
lodsb
cmp al,']'
loopne @SkipRange
jne @ChrNOk
@NNNChrOk:
dec bx
inc di
jmp @ChrOk
@No4DosChr:
cmp es:[di],al
jne @ChrNOk
inc di
dec bx
@ChrOk:
xor dh,dh
dec cx
jnz @ChkChr { Can't use loop, distance >128 bytes }
or bx,bx
jnz @ChrNOk
@ChrAOk:
mov al,1
jmp @EndR
@ChrNOk:
or dh,dh
jz @IChrNOk
jcxz @IChrNOk
or bx,bx
jz @IChrNOk
inc di
dec bx
jz @IChrNOk
mov ax,[LastW]
sub ax,cx
add cx,ax
sub si,ax
dec si
jmp @ChkChr
@IChrNOk:
mov al,0
@EndR:
pop ds
end;


在Delphi7下,编译到 lds si,SearchStr les di,NameStr 出错,高手给我个提示
 
你应当认为SearchStr和NameStr在汇编代码部分并不存在。
因为根据register调用约定,传递的前3个参数依次放入EAX, EDX, ECX中,因此这里SearchStr为EAX寄存器,NameStr为EDX寄存器, delphi编译器会自动将你的代码
lds si, SearchStr
替换成:
lds si, EAX
然后进行编译。显然这里是错误的。

大概瞄了一眼代码, 提醒一句, 最好不要把dos时代的16位代码原封不动的抄过来。那样的话即使编译通过运行也肯定出错。比如你的代码中就把SearchStr作为一个短字符串来处理(类似str: string[20]这种定义),而默认编译开关下delphi的字符串长度信息在-4偏移处,是个32位整数(应当用mov ecx, [eax-4]之类的语句来获取字符串长度)

另外,在32位变成环境下不要试图改变ds,es寄存器。

大概修改了一下第一部分代码, 看看你应该就知道怎么在32位环境下写asm了:
asm
push ebx
push esi
push edi // delphi要求必须保存ebx, esi, edi寄存器的值(如果你用到的话)
mov esi, eax
mov edi, edx
xor ecx, ecx
xor ebx, ebx
or eax, eax
jz @001 // SearchStr=''
mov ecx, [eax-4]
@001:
or edx, edx
jz @002 // NameStr=''
mov ebx, [edx-4]
@002:
or ecx, ebx
jz @chraok // (SearchStr='') and (NameStr='')
or ecx, ecx
jnz @chkchr // SearchStr<>''
jmp @chrnok // (SearchStr='') and (NameStr<>'')
@chkchr:
。。。
 
一睹 Another_eYes 大侠风采 [:)]
 
接受答案了.
 
后退
顶部