Hot answers tagged

10

I actually found the answer while writing this question! This number is exactly UINT_MAX + 1, stored as a double. So it seems this code converts a unsigned integer to a double. The fild instruction loads the 32 bit value as signed value, after adding the max possible unsigned value + 1, the double contains the same value as the unsigned integer. So the ...


9

You likely won't get an exact reproduction because cvtdq2pd takes the lower 64 bits of the second operand but since we're limited to 32 bits because we're using eax here, there are probably better(?) instructions to use. cvtsi2sd xmm0, eax will do the same thing as movd xmm0,eax cvtdq2pd xmm0,xmm0 See here https://www.felixcloutier.com/x86/CVTDQ2PD.html &...


6

COERCE_TYPE(x) is the same thing as *(TYPE *)&x. Hex-Rays uses COERCE_... macros when &x is illegal. For example: COERCE_DOUBLE(__PAIR__(i1,i2)) Is the same as *(double *)&__PAIR__(i1, i2), but since & can not be applied to calls, we end up seeing COERCE. Its name correctly conveys its meaning.


4

I assume it's just a simple cast. v29 = *reinterpret_cast< float* >( &v30 ); It would be easier if you'd share the generated assembly instead of the pseudo code.


4

To move a number into an XMM register, you'll first need to move that number into a memory address since you can't move an immediate into an XMM register (meaning, you can't do something like mov XMM1,9). If need be, you can allocate your own memory to store a number in, or in your scenario, if it's feasible, you could inject code to put your own value into ...


3

This appears to be a fixed-point (rather than a floating-point) format. If you treat the 64-bit values as signed integers and divide by 4398046511104.0, you will get the decimal values you show. e.g. the following will print -9999 #include <iostream> #include <cstdint> int main() { int64_t x = 0xFF63C40000000000LL; double y = x / ...


3

For starters you can encode/decode the military format to IEEE 754 this way you can use FPU and standard math stuff so at start everything would work. The code would look like this: military fabs(military x) { double _x; _x=military2double(x); _x=fabs(_x); return double2military(_x); } convert functions to your format ...


2

You are correct, and objdump is actually wrong to disassemble such instruction, only to mark it as (bad) in a later stage. Here is how it works: db a5 4e 9c 95 68 lock (bad) [rbp+0x68959c4e] db is one of the 87 FPU extensions, and a5 indeed is the Mod/rm byte. Now, for the FPU extensions, the rm part is "as usual" for all other mod/rm instructions, but ...


2

This isn't a complete answer but is a bit more than fits in a comment. There's definitely a pattern in the powers of 2. They all have exactly 4 bits set. The high bit is always 1 and the lower 15 bits seem to be the same bit pattern (11001) but rotated to different positions. Try filling in the gaps (32, 64, 128, 1024) and show in binary without spaces to ...


2

Maybe it is the temperature in Kelvin: 311 - 80/2 = 217K = -2.15°C Or the offset is different than 80/2. A 16-bit floating-poitn format, especially a different one from IEEE-754 is highly unlikely. Such measurement chips are not more but simple ADCs, they lack the capabilities to convert their reading to floating-point. To be sure, you would have to take ...


1

One word, precision By definition, a normal is a vector with a length of 1.0f which means that each component of the vector will always fall between -1.0f and +1.0f, and UV are texture coordinates expressed in a range between 0 and +1.0f. The number of possible states that you can represent with this range of numbers is huge and even exceeds the total ...


1

I have added some comments to the disassembly you posted, so it's easier to understand. sub esp, 8 ; stack frame fld [esp+8+arg_0] ; load value of arg0 to st fist [esp+8+var_8] ; store round(arg0) in var8 fisubr [esp+8+var_8] ; subtract arg0 from var8 fstp [esp+8+var_4] ; store result in var4 ;now var4 = round(arg0) - arg0 ...


1

After a little digging I got it. Right click your Dump to change data types between address and float. You have to follow the address of the address pointed to by esp-4 to get the parameters.


1

The IEEE 754 standard describes how the floating point representation works under the hood.


1

Although you indeed cannot use mulss with an immediate value like you've pointed out, you are allowed to pass an 32bit offset as mulss's second operand: Multiplies the low single-precision floating-point value from the source operand (second operand) by the low single-precision floating-point value in the destination operand (first operand), and stores ...


1

FCOMP Compares the fpu register ST0 with a constant the constant is a QWORD (Meaning DOUBLE , FLOAT , Etc 8+ bytes wide ) ollydbg can show both the ST0 register and decipher the contents of the CONSTANT . in your case if shows DB 00 because the constant is probably 0.0 . and you have not set the dump view mode to appropriate format the view ...


1

Understanding the assembly line FCOMP QWORD PTR DS:[402CB0] It checks for a qword sized operand. That is 8 bytes while your picture only shows about 3. This comparison is also a floating point comparison, which is a bit more complex than an integer comparison. It sets three control registers (C0, C2, C3) depending on the outcome and raises an exception ...


1

These casts are done to make the pointer arithmetic that's happening more clear. When you add an integer to a pointer, the integer internally gets multiplied by the size of the object the pointer is pointing to, so when fp is a float pointer, assuming 4 byte floats, fp+1 will point to a memory location 4 bytes behind fp. And in the same way, pointer ...


1

coerce_* functions are generally a little more coercive that a simple casting, I would assume their meaning as follows: #define VALUE_SIZE (sizeof(int)) struct VALUE_TYPE { char contents[VALUE_SIZE]; }; struct VALUE_TYPE COERCE_FLOAT(float arg) { struct VALUE_TYPE rv; memcpy(&arg, rv.contents, sizeof arg); return rv; } struct ...


1

I'd read this (and probably it is a mistake) as treating binary content of the variable as a variable of another type, something like this: coerce float is *((float*)&var), where var was of the same size as float, supposedly 4 bytes. coerce unsigned int is *((unsigned int*)&var), where var was of the same size as unsigned int. As far as I remember ...


1

sub esp, 8 movsd xmm0, ds:MEMORY1 ; mov 128-bit memory movsd [esp], xmm0 Fetch MEMORY1. This will be our denominator in fmod(). mov eax, [ebp+ItirationCounter_var_60] mov [ebp+CurrentCounter_var_A8], eax cvtsi2sd xmm0, [ebp+CurrentCounter_var_A8] ; Convert to floating point into xmm0 Fetch Counter as a floating-point number. This will be ...


Only top voted, non community-wiki answers of a minimum length are eligible