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?