如何在GNU GAS中使用十六进制浮点文字? [英] How to use hexadecimal floating point literals in GNU GAS?
问题描述
C99引入了十六进制浮点文字作为一种新的代码混淆技术,例如:
C99 introduced hexadecimal floating point literals as a new code obfuscation technique, e.g.:
assert(0x1.8p0 == 1.5);
我可以在我的GNU GAS汇编代码中实现相同程度的混淆吗?还是我必须求助于.byte
+体力劳动?
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
这是GitHub上更可运行的版本,其中一个断言,如果您想对其进行测试.
如果我尝试例如:
float_1_5: .double 0x1.8e0
GAS 2.30只是将其视为1.8(大约无法表示),这是非常棒的行为!
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: junk at end of line, first unrecognized character is `p'
一个人可以和平地控制其IEEE 754重要数字的52位吗?
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?
推荐答案
cpp
宏+ GAS位操作变通方法
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)
用法:
.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)
主要的烦恼是您必须正确设置52个尾数位.但是,一旦完成第一个操作,就只需复制即可粘贴并更改位.
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.
带有断言的可运行GitHub上游:
Runnable GitHub upstream with assertions:
- assembly usage
- macro definitions
这篇关于如何在GNU GAS中使用十六进制浮点文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!