Смешивание c ++ и ассемблера не может передать несколько параметров из функции C ++ в ассемблер

Я был разочарован передачей параметров из функции c ++ в сборку. Я не смог найти что-нибудь, что помогло бы в Google и действительно нуждалось бы в вашей помощи. Я использую Visual Studio 2017 и masm для компиляции моего кода сборки.

Это упрощенная версия моего файла c ++, где я вызываю процедуру сборки set_clock

int main()
{
    TimeInfo localTime;
    char clock[4] = { 0,0,0,0 };
    set_clock(clock,&localTime); 
    system("pause");
    return 0;
}

Я столкнулся с проблемами в файле сборки. Я не могу понять, почему второй параметр, переданный функции, оказывается огромным. Я сходил с учебника, в котором показан аналогичный код с PROC, за которым следуют параметры. Я не знаю, почему первый параметр прошел успешно, а второй - нет. Может кто-нибудь сказать мне правильный способ передачи нескольких параметров?

.code
set_clock PROC, 
    array:qword,address:qword
    mov rdx,array   ; works fine memory address: 0x1052440000616
    mov rdi,address ; value of rdi is 14757395258967641292
    mov al, [rdx] 
    mov [rdi],al    ; ERROR: cant access that memory location
    ret
set_clock ENDP
END
4 голоса | спросил st4rgut 24 Mayam18 2018, 07:57:23

1 ответ


0
Чудо высокого уровня от MASM кусает тебя в задницу.x64 Windows передает первые 4 аргумента в ---- +: = 0 =: + ---- , ---- +: = 1 =: + ---- , ---- +: = 2 =:+ ---- , ---- +: = 3 =: + ---- (для любого из тех 4, которые являются целыми числами /указателями).собирает вИспользуйте дизассемблер, чтобы проверить себя.Всегда хорошая идея проверять реальный машинный код, разбирая или используя разборку ваших отладчиков вместо режима исходного кода, если с макросами на ассемблере происходит что-то странное.Я не уверен, почему это привело бы к недоступной ячейке памяти .Если оба аргумента действительно являются указателями на локальные объекты, тогда он должен просто загружаться и сохраняться в том же месте стека.Но если ---- +: = 6 =: + ---- - это ---- +: = 7 =: + ---- в статическом хранилище, это может быть страница памяти только для чтения, котораяобъяснить магазин провал.В любом случае, используйте отладчик и узнайте.Кстати, ---- +: = 8 =: + ---- - это сохраняемый вызов (он же энергонезависимый) регистр в соглашении x64 Windows.( https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx ).Используйте регистры с ограниченным вызовом для чистых регистров, если вы не исчерпали себя и не хотите сохранить /восстановить некоторые сохраненные вызовы регистры.См. Также документ Соглашения о вызовах Agner Fog ( http://agner.org/optimize/) и другие ссылки в вики-теге x86 .Он закрыт в x86-64 System V, который также передает аргументы в разные регистры.Может быть, вы смотрели на другой пример?Надеюсь, исправлена ​​версия, использующая ---- +: = 9 =: + ----, чтобы избежать ложной зависимости от RAX при загрузке байта.Я не использую MASM, но я думаю, что ---- +: = 11 =: + ---- делает ---- +: = 12 =: + ---- псевдоним для ---- +:= 13 =: + ---- .Или вы можете пропустить объявление параметров и просто использовать ---- +: = 14 =: + ---- и ---- +: = 15 =: + ---- и задокументировать его с комментариями.Это было бы легче понять всем.Вам определенно не нужны бесполезные ---- +: = 16 =: + ---- инструкции, загромождающие ваш код;если вы пишете в asm в первую очередь, напрасные инструкции будут сокращать любые ускорения, которые вы получаете.
ответил Peter Cordes 24 Mayam18 2018, 08:19:15

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132