2

C99 introduced hexadecimal floating point literals as a new code obfuscation technique, e.g.:

assert(0x1.8p0 == 1.5);

Can I achieve the same level of obfuscation in my GNU GAS assembly code, or do I have to resort to .byte + manual labor?

You may use this as a testing base:

.data
    float_1_5: .double 1.5
    float_2_5: .double 2.5
    float_4_0: .double 4.0
.text
.global _start
_start:
    /* 1.5 + 2.5 == 4.0 */
    fldl float_1_5
    fldl float_2_5
    faddp %st, %st(1)
    fldl float_4_0
    fcomip %st(1)

    /* Exit syscall. */
    mov $1, %eax
    mov $0, %ebx
    int $0x80

Here is a more runnable version on GitHub with an assert if you want to test it out.

If I try e.g.:

    float_1_5: .double 0x1.8e0

GAS 2.30 just happily treats it as 1.8 (approximately since not representable), wonderful behavior!

And the following just fails to assemble, which is at least not as bad:

    float_1_5: .double 0x1.8p0

Error:

 Error: junk at end of line, first unrecognized character is `p'

Can a man control the 52 bits of his IEEE 754 significand in peace?

I've already given up on float literals directly on the .text area... How do I specify immediate floating point numbers with inline assembly?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985

1 Answers1

1

cpp macros + GAS bit manipulation workaround

This is not true hex floating point, but it is a reasonable intermediate between hex floats and writing raw floating point integer constants:

#define LKMC_FLOAT_64_SIGN_BITS 1
#define LKMC_FLOAT_64_EXP_BITS 11
#define LKMC_FLOAT_64_MANTISSA_BITS 52
#define LKMC_FLOAT_64_EXP_BIAS ((1 << (LKMC_FLOAT_64_EXP_BITS - 1)) - 1)
#define LKMC_FLOAT_64(sign, exp, mantissa) ((((sign << LKMC_FLOAT_64_EXP_BITS) | exp + LKMC_FLOAT_64_EXP_BIAS) << LKMC_FLOAT_64_MANTISSA_BITS) | mantissa)

usage:

.data
    double_1_5: .quad LKMC_FLOAT_64(0x0, 0x0, 0x8000000000000)
    double_2_5: .quad LKMC_FLOAT_64(0x0, 0x1, 0x4000000000000)
    double_4_0: .quad LKMC_FLOAT_64(0x0, 0x2, 0x0000000000000)

The major annoyance is that you have to get the 52 mantissa bits correct. But once you do the first one it is just a matter of copy pasting it around and changing the bits.

Runnable GitHub upstream with assertions:

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985