Почему вы делаете fstp qword
(double
) в тбайт (long double
)?
О, это, вероятно, ваша ошибка. Предположительно, макрос invoke
добавляет 12 байтов для каждого из аргументов макроса result
. (Потому что 10-байтовый tbyte
, добавленный к кратным 4-байтовым слотам стека, равен 12).
Но ваша строка формата только указывает sprintf искать double
аргументы, которые имеют ширину 8 байтов. Поскольку вы сохранили только qword double
в младших 8 байтах result
, crt_sprintf
может правильно прочитать первый аргумент c arg как double
. (x86 имеет младший порядок байтов, поэтому младшие 8 байтов находятся по адресу стека, который просматривает sprintf.)
Но второе преобразование %G
будет искать другое double
сразу после окончания предыдущего аргумента Который в соответствии со строкой формата должен быть через 8 байт. Но то, что на самом деле нажал invoke
, не соответствовало этому. Таким образом, 2-й %G
читает 8 байтов, которые перекрывают два 12-байтовых нажатия.
Это, вероятно, 0
в старших 4 байтах (включая биты экспоненты и знака) и ненулевое значение только в младшем 31 бит мантиссы, давая вам очень маленькое субнормальное число. Вы можете использовать отладчик для проверки памяти как double
и увидеть, что она представляет значение sprintf read.
Если long double
в этой библиотеке C является 10-байтовый тип x87, используйте %LG
и используйте fstp tbyte
.
Если sizeof(long double)
только 8, то это то же самое, что double
, и вы не можете печатать значения x87 тбайт с эта C библиотека. (Если у него нет нестандартного расширения для него.) В этом случае вы просто меняете result
на qword
, соответствующий магазину, который вы делаете.
Кроме того, вы не уравновесили стек x87; используйте faddp
, чтобы он пуст после fstp
. (Если вашему ассемблеру требуется операнд, используйте faddp st(1)
или st1
, однако ему нравится записывать имена регистров x87.)
Технически вы нарушаете соглашение о вызовах, делая вызов функции со стеком x87 не пустой, но, очевидно, crt_sprintf не использует все 8 из st0..7
, поэтому не получает NaN при переполнении стека x87.