Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с функциями. Нюансы.  (Прочитано 8640 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« : 25-08-2017 08:22 » 

Доброго дня.

Вчера, пока писал, обратил внимание на нюанс, и поэтому хочу задать вопрос: кто должен сохранять актуальные значения регистров? Функция, которую вызывают? Или вызывающая сторона?

Может я уже подзабыл, но сам всегда сохранял внутри функции те регистры, которые использовал, чтобы была прозрачность для программы.
Код: (ASM)
print_digit:

    push      eax
    push      ecx; Вот это было добавлено, так как >>
    mov       eax, DWORD line
    add       eax, edx
    push      DWORD 0
    push      DWORD written
    push      DWORD 1
    push      eax
    push      DWORD [stdout]
    call      _WriteConsoleA@20; >> здесь изменяется ecx.
    pop       ecx; А здесь я восстанавливаю его прежнее значение, чтобы
                 ; не сбить вызывающую программу.
    pop       eax
    ret
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 25-08-2017 09:05 » 

зависит от Соглашение о вызове(Calling convention)

PS ну и архитектуры процессора конечно, строго говоря.
« Последнее редактирование: 25-08-2017 09:08 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 25-08-2017 09:25 » 

Тут речь об WinApi (stdcall), но он описывает передачу данных через стек. А по поводу того, что функция не следит за сохранением регистров? То есть, eax, понятно - это выход результата, но зачем трогать ecx? Просто в таком случае придётся перед вызовом в общем случае писать pusha, но это же долго будет выполняться.
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 25-08-2017 09:53 » 

в смысле "Тут речь об WinApi (stdcall)"? - вы об приведенном куске кода?
Цитата
x86 при 32-битной адресации...
Для перечисленных ниже соглашений (кроме cdecl) перед возвратом значений из функции подпрограмма обязана восстановить значения сегментных регистров, регистров esp и ebp. Значения остальных регистров могут не восстанавливаться.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 25-08-2017 10:20 » 

Да.

То есть, придётся перед вызовом перестраховаться и записать в стек до загрузки аргументов все регистры. А потом после их извлечь.

Логика просто странная, предположим у меня в функции четыре регистра используются, а в х64 их тьма, значит в прологе придётся сохранить всё.
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 25-08-2017 10:33 » 

внимательнее. я написал "x86 при 32-битной адресации..."
для x64 https://msdn.microsoft.com/ru-ru/library/ms235286.aspx#Соглашение о вызовах
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 25-08-2017 10:58 » 

Спасибо.

Собственно для себя уяснил:
Цитата
Регистры RAX, RCX, RDX, R8, R9, R10 и R11 считаются временными и должны уничтожаться при вызове функции (если иное не требуется, исходя из соображений безопасности, например в процессе оптимизации программы).

Регистры RBX, RBP, RDI, RSI, RSP, R12, R13, R14 и R15 считаются защищенными. Значения этих регистров должны сохраняться и восстанавливаться в использующей их функции.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines