У меня есть однострочная функция C, которая просто return value * pow(1.+rate, -delay);
- она дисконтирует будущую стоимость к текущей стоимости. Интересная часть разборки
0x080555b9 : neg %eax
0x080555bb : push %eax
0x080555bc : fildl (%esp)
0x080555bf : lea 0x4(%esp),%esp
0x080555c3 : fldl 0xfffffff0(%ebp)
<b>0x080555c6 : fld1 </b>
0x080555c8 : faddp %st,%st(1)
0x080555ca : fxch %st(1)
0x080555cc : fstpl 0x8(%esp)
0x080555d0 : fstpl (%esp)
0x080555d3 : call 0x8051ce0
0x080555d8 : fmull 0xfffffff8(%ebp)
При пошаговом выполнении этой функции, говорит GDB (скорость 0,02, задержка 2; вы можете видеть их в стеке):
(gdb) si
0x080555c6 30 return value * pow(1.+rate, -delay);
(gdb) info float
R7: Valid 0x4004a6c28f5c28f5c000 +41.68999999999999773
R6: Valid 0x4004e15c28f5c28f6000 +56.34000000000000341
R5: Valid 0x4004dceb851eb851e800 +55.22999999999999687
R4: Valid 0xc0008000000000000000 -2
=>R3: Valid 0x3ff9a3d70a3d70a3d800 +0.02000000000000000042
R2: Valid 0x4004ff147ae147ae1800 +63.77000000000000313
R1: Valid 0x4004e17ae147ae147800 +56.36999999999999744
R0: Valid 0x4004efb851eb851eb800 +59.92999999999999972
Status Word: 0x1861 IE PE SF
TOP: 3
Control Word: 0x037f IM DM ZM OM UM PM
PC: Extended Precision (64-bits)
RC: Round to nearest
Tag Word: 0x0000
Instruction Pointer: 0x73:0x080555c3
Operand Pointer: 0x7b:0xbff41d78
Opcode: 0xdd45
А после fld1
:
(gdb) si
0x080555c8 30 return value * pow(1.+rate, -delay);
(gdb) info float
R7: Valid 0x4004a6c28f5c28f5c000 +41.68999999999999773
R6: Valid 0x4004e15c28f5c28f6000 +56.34000000000000341
R5: Valid 0x4004dceb851eb851e800 +55.22999999999999687
R4: Valid 0xc0008000000000000000 -2
R3: Valid 0x3ff9a3d70a3d70a3d800 +0.02000000000000000042
=>R2: Special 0xffffc000000000000000 Real Indefinite (QNaN)
R1: Valid 0x4004e17ae147ae147800 +56.36999999999999744
R0: Valid 0x4004efb851eb851eb800 +59.92999999999999972
Status Word: 0x1261 IE PE SF C1
TOP: 2
Control Word: 0x037f IM DM ZM OM UM PM
PC: Extended Precision (64-bits)
RC: Round to nearest
Tag Word: 0x0020
Instruction Pointer: 0x73:0x080555c6
Operand Pointer: 0x7b:0xbff41d78
Opcode: 0xd9e8
После этого все идет в ад. Вещи сильно переоценены или недооценены, поэтому, даже если бы в моей попытке свободного ИИ не было других ошибок, он выбрал бы все неправильные стратегии. Как отправка всей армии в Арктику. (Вздох, если бы я только зашел так далеко.)
Я, должно быть, упускаю что-то очевидное или что-то ослепляю, потому что не могу поверить, что fld1
может когда-нибудь потерпеть неудачу Тем более, что он должен потерпеть неудачу только после нескольких проходов через эту функцию. На более ранних проходах FPU правильно загружает 1 в ST (0). Байты в 0x080555c6 определенно кодируют fld1
- проверено с помощью x / ... в запущенном процессе.
Что дает?