![]() |
![]() |
![]() |
|||||
![]() |
![]() |
![]() |
![]() |
![]() |
|||
| Welcome
to Tech Support Forum home to more then 136,000 problems solved. Issues
have included: Spyware, Malware, Virus Issues, Windows, Microsoft,
Linux, Networking, Security, Hardware, and Gaming Getting your
problem solved is as easy as: 1. Registering for a free account 2. Asking your question 3. Receiving an answer Registered members: * See fewer ads. * And much more..
|
| Want to know how to post a question? click here | Having problems with spyware and pop-ups? First Steps |
|
|||||||
| Programming A discussion forum for programs and programming used in tech-related businesses. |
![]() |
|
|
LinkBack | Thread Tools |
|
|
#1 (permalink) |
|
Registered User
|
Few handy routines.
Just a few general-purpose I wrote for a project which I thought I'd share.
NOTE: Requires an x86/x64-based processor. (This includes AMD, and many others). Code:
/*
* Utility.cpp
* ===========
* Copyright (C) Matthew J. W.
* Version 1.0
*
*
* Description:
* Implementation of the Utility module.
*
*
* Abstract:
* The Utility module covers routines which are of a strictly general-purpose
* nature.
*
*
*******************************************************************************************************************************************************/
#include "BnetDiagTool.h"
////////////////////////////////////////////////////////////////////////////
//
// Math Functions
//
////////////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------------
// Dword PowerOf(Dword, Dword)
// -=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// Description:
// Calculates a base raised to a certain power.
//
//
// Parameters:
// [Dword] 'dwBase' - Base being raised.
// [Dword] 'dwExponent' - Power the base is being raised to.
//
//
// Return Value:
// Returns 'dwBase' raised to the power of 'dwExponent'.
//
//
Dword __fastcall PowerOf(Dword dwBase, Dword dwExponent)
{
__asm
{
/*
* ECX - Base.
* EBX - Exponent.
* EAX - Result.
*
*/
// Save registers we'll be using, to ensure we don't interfer with the
// caller. Also save operation flags.
pushfd
push ecx
push ebx
push edx
// Initialize.
mov ebx, edx
xor edx, edx
mov eax, 1
// If we have no exponent, the result is always 1.
cmp ebx, 0
je EXIT
RAISE_POWER:
// Raise the base.
mul ecx
dec ebx
// Have we raised to the appropiate power?
cmp ebx, 0
jne RAISE_POWER
EXIT:
// Return original registers, and operation flags.
pop edx
pop ebx
pop ecx
popfd
}
}
////////////////////////////////////////////////////////////////////////////
//
// String Functions
//
////////////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------------
// Dword GetStringLength(Char*)
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// Description:
// Retrieves the length of a null-terminated, ascii string.
//
//
// Parameters:
// [Char*] 'pstr' - The string in question.
//
//
// Return Value:
// Returns the length of 'pstr'.
//
//
Dword __fastcall GetStringLength(const Char* pstr)
{
__asm
{
/*
* ECX - Pointer to the string.
* EAX - Buffer for blocks read from the string.
* EBX - Pointer to the first element of the string.
*
*/
// Save registers we'll be using, to ensure we don't interfer with the
// caller. Also save operation flags.
pushfd
push ecx
push ebx
// Remember the starting address of the string.
mov ebx, ecx
READ_BLOCK:
// Read a 4-byte block of the string.
mov eax, dword ptr [ecx]
// Is byte-0 the terminator?
test eax, 0x000000FF
jz FOUND_NULL
// Is byte-1 the terminator?
test eax, 0x0000FF00
jz FOUND_NULL
// Is byte-2 the terminator?
test eax, 0x00FF0000
jz FOUND_NULL
// Is byte-3 the terminator?
test eax, 0xFF000000
jz FOUND_NULL
// Move on to the next block.
add ecx, 4
jmp READ_BLOCK
FOUND_NULL:
/*
* Now that we've found the block which contains the null-terminator, it's time
* to figure out which exact byte is the terminator itself.
* Keeping in mind, if the first three bytes are _not_ null, then the fourth
* byte _must_ be.
*
*/
test eax, 0x000000FF
jz EXIT
inc ecx
test eax, 0x0000FF00
jz EXIT
inc ecx
test eax, 0x00FF0000
jz EXIT
inc ecx
EXIT:
// To calculate the length of the string, we find the difference between
// it's starting address(EBX) and the address of the null-terminator(ECX).
sub ecx, ebx
mov eax, ecx
// Return original registers, and operation flags.
pop ebx
pop ecx
popfd
}
}
//--------------------------------------------------------------------------
// Byte CharToInt(Char)
// -=-=-=-=-=-=-=-=-=-=
//
// Description:
// Converts a ascii-character to an integer.
//
//
// Parameters:
// [Char] 'c' - The character to be converted.
//
//
// Return Value:
// Returns the binary integer of which 'c' represents.
//
//
// Notes:
// # Only the binary, octal, decimal and hexadecimal number-systems are supported.
// # The result is undefined if an improper value is given.
//
//
Byte __fastcall CharToInt(Char c)
{
__asm
{
/*
* CL - The character being converted.
*
*/
// Is the character _not_ of the binary, octal or decimal systems?
cmp cl, 0x39
jg HEXADECIMAL
// Binary, octal or decimal.
sub cl, 0x30
jmp EXIT
HEXADECIMAL:
// Are we dealing with a lower-case hex-digit?
cmp cl, 0x46
jg LOWER_CASE_HEX
// Upper-case hexadecimal.
sub cl, 0x37
jmp EXIT
LOWER_CASE_HEX:
// Lower-case hexadecimal.
sub cl, 0x57
EXIT:
mov al, cl
}
}
//--------------------------------------------------------------------------
// Char IntToChar(Byte)
// -=-=-=-=-=-=-=-=-=-=
//
// Description:
// Converts a binary integer to an ascii-character.
//
//
// Parameters:
// [Byte] 'b' - The integer to be converted.
//
//
// Return Value:
// Returns the character representation of 'b'.
//
//
// Notes:
// # Only the binary, octal, decimal and hexadecimal number-systems are supported.
// # The result is undefined if an improper value is given.
// # Hexadecimal digits are always outputted in upper-case form.
//
//
Char __fastcall IntToChar(Byte b)
{
__asm
{
/*
* CL - The integer being converted.
*
*/
// Is the integer _not_ part of the binary, octal or decimal systems?
cmp cl, 0x9
jg HEXADECIMAL
// Binary, octal or decimal.
add cl, 0x30
jmp EXIT
HEXADECIMAL:
// Hexadecimal.
add cl, 0x37
EXIT:
mov al, cl
}
}
//--------------------------------------------------------------------------
// Dword StrToInt(Char*, Dword)
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// Description:
// Converts a string of characters representing a number to an actual binary
// integer.
//
//
// Parameters:
// [Char*] 'pstr' - The string to be converted.
// [Dword] 'dwBase' - The base system in which the string should be interpreted as.
//
//
// Return Value:
// Returns the integer representation of 'pstr'.
//
//
Dword __fastcall StrToInt(const Char* pstr, Dword dwBase)
{
__asm
{
/*
* ECX - Pointer to the number string ('pstr').
* ESI - The base system ('dwBase').
* EBX - Current positional value.
* EDI - Stores (accumulatively) the binary integer result.
*
*/
// Save registers we'll be using, to ensure we don't interfer with the
// caller. Also save operation flags.
pushfd
push ebx
push ecx
push edx
push esi
push edi
push ebp
// EDX ('dwBase') will be stored in ESI to avoid algorithm conflict.
mov esi, edx
/*
* Before we can begin converting the string, we must calculate the positional
* value of the left-most digit. This will enable us to able to convert the
* string left-to-right, hence from the first string element, to the last.
*
* The algorithm for retrieving the positional-value is simple, raise the
* base system by the length of the string (minus one).
*
*/
// First step, get the length of the string.
call GetStringLength
dec eax
// Temporarily store the string pointer in EDI.
mov edi, ecx
// Calculate the left-most digit's positional value.
mov ecx, esi // 'dwBase'
mov edx, eax // 'dwExponent'
call PowerOf
// Store the positional-value in EBX.
mov ebx, eax
// Return the string pointer to it's proper location (ECX).
mov ecx, edi
// Initialize the result to zero.
xor edi, edi
// Make sure the string pointer begins 4-bytes behind the start so
// it will conform with the following algorithm.
sub ecx, 4
// Begin converting the string to an integer.
NEXT_BLOCK:
// Point to the next block.
add ecx, 4
// Read a 4-byte block of the string.
mov eax, [ecx]
PROCESS_DIGIT:
// Have we encountered the null-terminator?
cmp al, 0
jz EXIT
// Is the character _not_ of the binary, octal or decimal systems?
cmp al, 0x39
jg HEXADECIMAL
// Binary, octal or decimal.
sub al, 0x30
jmp DIGIT_CONVERTED
HEXADECIMAL:
// Are we dealing with a lower-case hex-digit?
cmp al, 0x46
jg LOWER_CASE_HEX
// Upper-case hexadecimal.
sub al, 0x37
jmp DIGIT_CONVERTED
LOWER_CASE_HEX:
// Lower-case hexadecimal.
sub al, 0x57
DIGIT_CONVERTED:
// Temporarily store the digit block in EBP.
mov ebp, eax
// Multiply the digit by it's positional value, to get the ultimate value
// of the digit.
movzx eax, al
mul ebx
// Add the value of the digit to the result.
add edi, eax
// Calculate the positional-value of the next digit to the right.
mov eax, ebx
div esi
mov ebx, eax
// Return the digit block to EAX.
mov eax, ebp
// Mask out the digit just processed, and load the next digit into AL.
mov al, 0xFF
ror eax, 8
// Have we completed the whole block?
cmp eax, 0xFFFFFFFF
jz NEXT_BLOCK
// Process the next digit.
jmp PROCESS_DIGIT
EXIT:
// Return the result of the conversion.
mov eax, edi
// Return original registers, and operation flags.
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
popfd
}
}
Last edited by MattBro; 01-02-2007 at 06:34 AM. |
|
|
|
| Important Information |
|
Join the #1 Tech Support Forum Today - It's Totally Free!
TechSupportForum.com is a leading support website for your computer needs. We offer free, friendly and personalized computer support. Why pay to have your computer fixed when you can do it for free. Join TechSupportforum.com Today - Click Here |
![]() |
| Thread Tools | |
|
|