этот указатель в документе clr abi


person Jason    schedule 22.08.2016    source источник
comment
Буфер возврата описан в разделе Возвращаемые значения в документации MSDN для x64. соглашения о вызовах: В противном случае вызывающая сторона берет на себя ответственность за выделение памяти и передачу указателя на возвращаемое значение в качестве первого аргумента.   -  person Harry Johnston    schedule 22.08.2016


Ответы (1)


Понятно, что Microsoft возится со своим x64 abi. Что именно они сделали и когда, однако, совершенно неясно, документация неполная, разбросанная и плохо датированная. Я лично считаю работу по обратному инжинирингу, проделанную Агнером Фогом, единственным действительно надежным источником информации. Однако он не занимается генерацией управляемого кода.

Утверждение, что это было изменено в 4.5, довольно неправдоподобно. Гораздо более вероятно, что это было изменено в RyuJIT, новом джиттере x64, чтобы заменить довольно глючный и неуправляемый джиттер x64. Первоначально выпущенный в предварительной версии как 4.5.3, что, возможно, объясняет претензию 4.5, но позже был увеличен до 4.6. Вероятным источником вдохновения для этого изменения является проект .NETCore, разница abi Microsoft x64 с генераторами кода Unix (GNU и LLVM) довольно болезненна.

Но в отличие от изменений генератора кода компилятора C++ (модифицированных в обновлении VS2015 в соответствии с Agner Fog, gack), это изменение вряд ли сломается. Несоответствие могло произойти только в pinvoke, джиттер никогда не поддерживал CallingConvention.ThisCall. К счастью, на ваши вопросы легко ответить:

Что означает буфер?

Это имеет значение только для методов, которые возвращают "агрегатный тип". Другими словами, значение, которое больше не помещается в регистры ЦП. В C# это struct, с дополнительным условием, что он должен быть нетривиальным (более 2 членов или нетривиальный тип поля).

Вызывающий метод должен выделить место в своем кадре стека для возвращаемого значения («буфер») и передать указатель на это пространство. Этот указатель передается как скрытый дополнительный аргумент метода. Традиционно первый аргумент перед скрытым аргументом this. Это сделало this вторым аргументом и, следовательно, передавалось через регистр RDX вместо регистра RCX. Изменение меняет порядок, this всегда является первым аргументом и передается через RCX, указатель возвращаемого значения является вторым. Вызванный метод копирует возвращаемое значение в этот буфер перед возвратом.

Как насчет того, чтобы использовать статический класс

Относится только к статическому методу. Тогда нет дополнительного скрытого аргумента this, поэтому он просто опускается. По сути, никаких изменений по сравнению с тем, как это было сделано раньше, скрытый указатель возвращаемого значения автоматически всегда является первым аргументом и, таким образом, передается через RCX.

Если это важно для вас, обязательно воспользуйтесь окном Debugger > Windows > Disassembly. Запустите его на небольшой тестовой программе, она легко подскажет, какие регистры используются.

person Hans Passant    schedule 22.08.2016