Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

HyperStr - Operand Size Mismatch

Status
Not open for further replies.

ThunderForest

IS-IT--Management
Mar 3, 2003
189
US
I'm responsible for an application that made ample, and extensive use of HyperStr, a 3rd party string library that apparently was no longer supported or upgraded following Delphi 5. Google turns up dead ends on the author. I need to upgrade the application to v7 for other reasons, but it crashes during the compile in Hyperstr.Pas (see below), Operand Size Mismatch in Delphi 7. No problem with Delphi 5. It will crash at every occurence of the "Bt" line. The values in that line are apparently not equal, but I don't know why. Unfortunately, my assembler background is quite limited. I could easily write my own string functions, but the application is rather massive and really took advantage of what HyperStr had to offer, that is, assembler. Before I begin pounding out code, anyone experience this and have any ideas? Thanks.

begin
UniqueString(Source); //start with a unique string
asm

Push EBX //save the important stuff
Push ESI
Push EDI
Push EBP

Mov EAX,Source // Copy Source to EAX
Or EAX,EAX
Jz @Exit
Mov EAX,[EAX]
Mov EDX,Table
Mov ECX,Index
Call _TableScanIni // Procedure
Jecxz @Abort
Push ECX // save length
Sub ECX,EAX
Mov EBX,ESI // use EBX as write pointer
Xor EAX,EAX

@Next:
Lodsb //Load source into AL
Mov DL,AL //save it in DL
Mov DH,DL //and in DH
And DL,31 //bit index - doubleword is 31
Shr EAX,5 //dbl-word index
Shl EAX,2
Mov EBP,[EDI+EAX] //get the dbl-word

//CRASH OCCURS AT NEXT LINE

Bt EBP,DL //Bit Test

Jc @Skip //skip write if in Table
Mov [EBX],DH
Inc EBX
@Skip:
Dec ECX
Jnz @Next
Pop EAX //original source length
Mov DH,32 //prepare to space fill
@L3:
Cmp EBX,ESI //read = write ?
Jz @Exit //yes, then we're done
Mov [EBX],DH //no, then space fill
Inc EBX
Dec EAX //adjust output length
Jmp @L3 //and do it again

@Abort:
Xor EAX,EAX
@Exit:

Pop EBP //restore the world
Pop EDI
Pop ESI
Pop EBX
Mov Result,EAX //output length
end;
end;

Getting answers before I'm asked.
Providing answers if I can.
 
Bt EBP,DL //Bit Test

Instruction meaning: EBP is pointing to some data, DL is indexing a bit into that data, the bit indexed is copied into the carry flag (CF).

Problem: to the best of my knowledge, BT can't take a 8 bits register (DL) as the second operand, only an 8 bit inmediate value (constant) or a 16 (DX) or 32 bit (EDX) register. The instruction is incorrect.

How the D5 assembled managed to assembly the failing instruction: probably it entered in a "quirk mode" of sorts and used DX instead of DL.

Being so, replace BT EBP,DL by BT EBP,DX and it is done.

Due to the instruction NOT altering the operands, we are not changing his values, so the high part of DX will be safe.

Test both versions (the D5 and the new one) thoroughly. Please, understand that I'm are betting high here as I don't really know what the D5 assembly was making. If the code fails tell me here, may be I can produce a better (and more complex) solution.

buho (A).
 
Thanks, and DX worked (no compile errors anyway). Stars for you. This was above the Begin:

function DeleteI(var Source:AnsiString;const Table:AnsiString; const Index:Integer):Integer;

{Convert Table chars. from Index position forward into right justified spaces
which can be deleted if necessary using RTrim or SetLength.

Returns: Valid char. count; length minus chars. converted to spaces.}

//EFD961109

Getting answers before I'm asked.
Providing answers if I can.
 
The risk is not at compilation time, code will compile. The risk is I making a wrong assumption about how the D5 assembler "quirked" the instruction and generating a bug.

Second, for what I remember, the bit index is counted left to right, so the 3th bit of DL (an 8 bit entity) is the 3th bit of DX (a 16 bit entity) too. But if I'm wrong (and the index is counted right to left -very unlikely) I'm introducing a bug in the code.

Make a program with, say, 50 different strings; compile it in D5 and D6, run both versions and carefully compare the results. Try to stress the patched function(s) -using complex strings- to be sure they work the same.

buho (A).
 
Very good idea. Thanks for your help, and I'll try to keep you posted.

Getting answers before I'm asked.
Providing answers if I can.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top