//no type checking here.
mov ebx, dword ptr ds:[40302C] //a string from user input
movsx edx, byte ptr ds:[eax+40341E] //one byte of a static string varibale
sub ebx,edx
imul ebx,edx
...
so basically this is visually equivalent to
1 2 3 4 5 6 7 8 9 10 11 12
const std::string static_var{"ABCDEFGHIJKLMNOPQRSTUVWXYZ12345"};
std::string user_data{};
std::cout << "Enter your data\n";// you can input any alphanumeric sequence
std::cin >> user_data;
int var1 = /*first four most significant bytes of variable user_data, I'm not sure how I would copy them in c++ because of type checking*/
int var2 = /*sign extended first byte of static_var to fit into 32 bits variable*/
var1 -= var2 //sub ebx,edx
var1 *= var2 //imul ebx,edx
Is there any way I could repricate the above asm code in c++?
edit1:
An example:
1 2 3 4 5 6 7 8
//if I input the following string "AAAAA" then:
user_data = "AAAAA"
static_var{"%MNOPQRSTUVWXYZ1234506789"};
mov ebx, dword ptr ds:[40302C] //ebx would contain the first 4 bytes of AAAAA that would be ebx == 0x41414141 because hex_of_char('A') == 0x41
movsx edx, byte ptr ds:[eax+40341E] //any byte of the static string var, let's say the first so edx == 0x25 because hex_of_char('%') == 0x25
sub ebx,edx // ebx == 0x41414141, edx == 0x25 so ebx = 0x41414141 - 0x25 == 0x4141411C
imul ebx,edx // ebx == 0x4141411C, edx == 0x25 so ebx = 0x4141411C * 0x25 == 6E6E690C
Well, obviously it's not going to work to just get one byte.
It's designed to get an int's worth of bytes.
If you want the one byte, just access it with the subscript operator.
Thank you very much guys, the first problem of acquiring raw bytes is done but the integer values that I've gotten are in decimal form while in my asm code everything was in hexadecimal, if I do arithmetic operations on the decimal values(there's no way to perform hexadecimal arithmetics on c++) and then convert them into hexadecimal am I guaranteed to get the same result as in my asm code?
the computer only stores integers ONE way. That is in binary, effectively circuits that have power or not in the hardware. You can print it in binary, hex, decimal, octal, and other ways, but the bits are all the same in the hardware, that is just formatting of the output.
note that the ascii letters and hex digits are not directly convertible just as ascii decimal digit zero is not ascii 0. Do not think that "AAAA" string is 0xAAAA in hex at all.
It worked yea, but only when I hardcode the user input sometimes for example:
If i use the following input
1 2 3
user_input = "AGSD REID";//the program runs without errors when this is hardcoded into the algo.
//but when I acquire the same input from the console it doesn't work.
std::cin>>user_input; //it only seems to read the first half and discard the rest so user_input would contain "AGSD" only, very weird.
@jonnin note that the ascii letters and hex digits are not directly convertible just as ascii decimal digit zero is not ascii 0. Do not think that "AAAA" string is 0xAAAA in hex at all.
It took me sometimes to wrap my head around this but I finally got it, thank you.
As for the input problem any suggestions as to how I would solve it?
No. That is by design. string extraction from a stream only extracts up to but not including a white-space (space, tab, newline).
Thank you, I didn't know that was by design , thanks for the documentation it explains it clearly.
Finally to convert my computed decimal result into hex, I have this function:
better is subjective. the string to text and text to string built in tools are very, very slow**. There are a lot of pages, papers, code examples, and more on extremely ugly ways to 'fix' this when you need high performance. Its a rabbit hole though, and its best left undug unless you are trying to process data that would take hours doing it the 'slow' way.
**slow is relative. For printing on the screen, it won't matter. Printing on the screen is slow too! You will only really notice it if dumping to a file or something faster than screen and when processing multi-million string sets.
better is subjective. I meant faster in terms of performance. The only reason I converted the asm to c++ is for the sole purpose of reproducing\documenting bugs and give my colleague a simple test case in c++ which details the bug. (she requested c++ and I perfectly reproduced it with your help.)
1) Integer formatters: value is converted to a string of digits in the given base (with no redundant leading zeroes).
...
Unlike other formatting functions in C++ and C libraries, std::to_chars is locale-independent, non-allocating, and non-throwing. Only a small subset of formatting policies used by other libraries (such as std::sprintf) is provided. This is intended to allow the fastest possible implementation that is useful in common high-throughput contexts. https://en.cppreference.com/w/cpp/utility/to_chars
#include <type_traits>
#include <string_view>
#include <string>
#include <charconv>
// designed with efficiency as the overriding goal:
// returns a view to a static internal buffer, which is overwritten on each call
template < typename T >
typename std::enable_if< std::is_integral<T>::value, std::string_view >::type hex_str_view( T value )
{
staticchar buffer[128] ;
constauto [ ptr, ec ] = std::to_chars( buffer, buffer+sizeof(buffer), value, 16 ) ;
return { buffer, std::size_t(ptr-buffer) } ;
}
// returns a string (copy of the characters in the view returned by hex_str_view)
template < typename T >
typename std::enable_if< std::is_integral<T>::value, std::string >::type hex_str( T value )
{
return std::string( hex_str_view(value) );
}