2016-12-01 16 views
-1

Так недавно мы узнали о операциях с плавающей запятой и получили несколько вопросов в качестве домашней работы.
Одним из них является:Вызов конвенции по плаванию в Nasm

«Запишите соглашение о вызовах одинарной точности поплавки!».

Так я знаю о xmm регистрах и знать, что двойной точности первый вход переходит в xmm0 и так далее.
Я искал тему в Google, но не смог найти ответ. Было бы неплохо, если бы кто-то помог мне по этому вопросу.

+2

'nasm' - это ассемблер, он не определяет соглашение о вызове. Это определено соответствующим ABI для вашей среды, о котором вы не сказали. Для linux и mac посмотрите [Документ SysV] (http://stackoverflow.com/questions/18133812/where-is-the-x86-64-abi-документированный), для просмотра окон в [msdn] (https: //msdn.microsoft.com/en-us/library/zthk2dkh.aspx). – Jester

+0

Соглашения о вызове/ссылки ABI doc в [x86 tag wiki] (http://stackoverflow.com/tags/x86/info). О, вот что мой ответ по связанному вопросу уже говорит ... не проверял, чтобы увидеть, что связал Шут: P –

+1

Вопрос нарушается, потому что он предполагает, что существует такая вещь, как * "соглашение о вызовах *. Нет. Ответчик должен был быть более конкретным относительно *, который * вызывал соглашение, на которое они ссылались. У каждого из них разные правила. Как только вы узнаете о вызывающем соглашении, на которое ссылаетесь, вы можете легко найти его. –

ответ

1

Любое соглашение о вызове Я знаком с ручками одного float так же, как и double. (Не то, чтобы все вызывающие соглашения обрабатывали их одинаково, только в пределах одного соглашения о вызове нет diff).

Некоторые проходят в стек и возвращаются в x87 st (0).

Некоторые пропускают/возвращают в регистры XMM. (Связанный с этим факт: соглашение о вызове SysV не имеет регистров XMM, не содержащих вызовов, поэтому любой вызов функции означает пролитие всех значений FP, которые были в реальном времени в регистрах.)

См. Ссылки на документы ABI в теге .


Обратите внимание, что в 32-разрядное соглашения о вызовах, которые проходят double с в память о колл-стек, они берут в два раза больше пространства в виде целых чисел/указателей/float с. Таким образом, double занимает два слота стека.

Он может также иметь требование выравнивания 8B, ведущее к заполнению. Из-за этого они все еще не являются «специальными»: любой другой объект 8B с требованием выравнивания 8B (например, структура с членом alignas(8)) будет считаться одним и тем же.

+1

Единственный случай, когда я могу думать о том, где float и double могут обрабатываться по-разному, - это если у вас было соглашение о вызове на основе регистров для SSE (которое поддерживает только 32-битные поплавки), но ему пришлось вернуться в стек x87 для 64- бит удваивается. Но я не думаю, что такая конвенция на основе регистрации существует. __vectorcall требует поддержки SSE2. –