Here's my functions for fixing endianness
This is the ASM code needed to compile a DLL file that provides functions for swapping byte order (BigE to LittleE, or visa versa). The resulting DLL file is very useful in VB6 for code that reads or writes data from files that are used on a machine with BigEndian byte order, as Intel CPUs use LittleEndian byte order, and VB6 doesn't have any built-in functions to accomplish this.
This code is intended to be assembled with NASM and linked with GoLink.
Code:
EXPORT FixShort
EXPORT FixInt
SEGMENT .text
dllmain:
mov eax,1
ret 12
FixShort:
push ebp
mov ebp,esp
push edx
mov edx,[ebp+8]
mov eax,0
mov al,dh
mov ah,dl
pop edx
leave
ret 4
FixInt:
push ebp
mov ebp,esp
push edx
mov edx,[ebp+8]
mov al,dl
shl eax,8
shr edx,8
mov al,dl
shl eax,8
shr edx,8
mov al,dl
shl eax,8
shr edx,8
mov al,dl
pop edx
leave
ret 4
Note that Short here refers to a 16 bit integer (just like in C and C++), though would be called Integer in VB6.
Note that Int here refers to a 32 bit integer (just like in C and C++), though would be called Long in VB6 (despite Long meaning a 64 bit integer in C and C++).
And yes, even when I'm working with the 16 bit integers I use EAX instead of AX when handling the whole number, because VB6 actually uses 32 bit register opcodes for handling 16 bit numbers (if you disassemble a program written in VB6 you can see this) and then just calls additional functions to make sure that the number doesn't exceed the 16 bit limit, and triggers an error if it does. Same with the stack. VB6 uses 32 bit stack opcodes instead of 16 bit opcodes, even for 16 bit values.
Here are the proper declarations for using this DLL file's functions in VB6.
Code:
Private Declare Function FixShort Lib "endianfixer.dll" (ByVal Value As Integer) As Integer
Private Declare Function FixInt Lib "endianfixer.dll" (ByVal Value As Long) As Long
Change Private to Public if you are going to declare them in a Module for use elsewhere.
Re: Here's my functions for fixing endianness
Thanks for your code, bookmark it for later using!
Re: Here's my functions for fixing endianness
I don't do any assembly (any more). Is the FixInt code faster than just doing a single bswap operation on the eax register?
Re: Here's my functions for fixing endianness
Quote:
Originally Posted by
passel
I don't do any assembly (any more). Is the FixInt code faster than just doing a single bswap operation on the eax register?
I didn't know there was an x86 instruction to do byte swaps. I thought you had to manually move data with MOV instructions. If I knew about a byte swap instruction, I would have used that instead. Are there both 32 and 16 bit byteswap instructions, or only 32bit ones?
Re: Here's my functions for fixing endianness
As I said, I don't do asm any more, but I believe in the 286-386 days there was the XCHG operation to swap the ah, al bytes for 16 bits. I assume that is still valid for current processors. The bswap was added with the pentium for 32-bit registers I believe.
Re: Here's my functions for fixing endianness
i'd bet that there are also SSE commands for swapping Bytes. all that is the reason why it does not make any sense for me anymore writing handcrafted optimized ASM code: good Compilers take the optimal constructions and/or machine Hardware gets optimized for typical Compiler Output and in the end the asm code handcrafted in hours of work is still outperformed by three lines of C code that even are readable!
I also do have my doubts that it does provide any benefit to call an external dll function to swap two Bytes. if you'd pass in an Array and swap 1000s of Bytes then for sure, but just for two Bytes?! i'd guess the Overhead of the function call elimintes all the Speed benefit. and i also think that your asm code can be greatly optimized even without digging into SSE. for example i do not see a reason why the FixShort function could not just be one single ROL AX,8 command. the FixInt could by just a BSWAP EAX. but maybe i am wrong since i have not done any asm coding for years.