Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.08.2022, 17:38   #1
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 627
По умолчанию Всегда ли одинаковый порядок регистров

Делаю я, например, вот такой вот вызов процедуры
Код:
Procedure HalfBytes(const in1: byte; var out1, out2: byte); register;
После вызова проверил через CPU
In1 - al
out1 - edx
out2 - ecx

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

Последний раз редактировалось Kronos913; 26.08.2022 в 17:42.
Kronos913 вне форума Ответить с цитированием
Старый 26.08.2022, 17:43   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Пока не изменится соглашение вызова.

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Могу ли я сразу обращаться к регистрам, не перенося данные из них никуда?
За вас это сделал пролог функции.

http://docwiki.embarcadero.com/RADSt...ter_Convention
p51x вне форума Ответить с цитированием
Старый 26.08.2022, 17:48   #3
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Вопрос: всегда ли при вызове этой процедуры будут в таком порядке располагаться переменные в регистрах?
Могу ли я сразу обращаться к регистрам, не перенося данные из них никуда?
Можете. Только надо следить за тем, что не только порядок регистров важен, но и их длина. В типе вызова register всегда используются регистры eax, edx, ecx для первых трех параметров в этом порядке. Расширение аргументов до 32-х бит уже выполнено и то, что вы определили как byte уже расширено и занимает весь eax
macomics вне форума Ответить с цитированием
Старый 26.08.2022, 17:51   #4
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Пока не изменится соглашение вызова.
Это соглашение может измениться разве что при изменении архитектуры или платформы. Например, fastcall в x86_64 для первых 4-х параметров использует регистры rcx, rdx, r8, r9, но при передачи float/double значений эти же аргументы перемещаются в xmm регистры.
macomics вне форума Ответить с цитированием
Старый 26.08.2022, 17:52   #5
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 627
По умолчанию

Код:
Procedure HalfBytes(const in1: byte; var out1, out2: byte); register;
asm
  mov ah, 0
  shl eax, 4

  mov [edx], ah

  mov ah, 0

  shr eax, 4
  mov [ecx], al
end;
Есть вот такой вот простенький код. Тестирую на разных переменных - работает нормально

Есть ли риск ошибок при запуске на другом пк (с другой версией винды, или другом процессором), или при компиляции на другой версии Delphi ?
Kronos913 вне форума Ответить с цитированием
Старый 26.08.2022, 17:57   #6
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

mov ah, 0 - лишняя. Я же сказал, что byte уже расширили до dword. А учитывая, что byte - без знаковая, то и расширение было без знаковое (т.е. обнуление старших 24 бит).
Код:
Procedure HalfBytes(const in1: byte; var out2: byte): byte; register;
asm
    ror ax, 4
    shr ah, 4
    mov [edx], ah
    and eax, 15
end;
Зачем заставлять вычислять 2 указателя, когда одно из значений можно вернуть обычным образом (оставив его в eax)

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Есть ли риск ошибок при запуске на другом пк (с другой версией винды, или другом процессором), или при компиляции на другой версии Delphi ?
Риск есть всегда. Но пока компилятор следует этому типу вызова, то ошибок не будет. Вам же наверняка уже попадались программы не работающие уже даже на Win10, но работавшие на Win7 или WinXP и даже не хочу вспоминать про Win9x (типичный пример 16-битные консольные приложения)

Последний раз редактировалось macomics; 26.08.2022 в 18:06.
macomics вне форума Ответить с цитированием
Старый 26.08.2022, 19:28   #7
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 627
По умолчанию

Цитата:
mov ah, 0 - лишняя. Я же сказал, что byte уже расширили до dword. А учитывая, что byte - без знаковая, то и расширение было без знаковое (т.е. обнуление старших 24 бит).
Проверил - таки надо. Но больше для защиты от некорректного ввода
Kronos913 вне форума Ответить с цитированием
Старый 26.08.2022, 19:30   #8
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Если вы вместо byte передаете int и отключена проверка на диапазоны, тогда надо. Но если исходное значение у вас определено как переменная типа byte, тогда обнуление будет сделано за вас перед передачей параметра.
macomics вне форума Ответить с цитированием
Старый 26.08.2022, 19:56   #9
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 627
По умолчанию

Раз уж на то пошло, насколько оптимален этот код?
Код:
Procedure TColorToRGB(const Color:TColor; var r, g, b:byte); register;
asm
  mov [edx], al
  mov [ecx], ah

  shr eax, 8

  mov edx, b
  mov [edx], ah
end;
Kronos913 вне форума Ответить с цитированием
Старый 26.08.2022, 20:27   #10
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Не очень оптимален. Не забывайте, что для этой процедуры компилятор должен будет еще дополнительно вычислить адреса 3 указателей на переменные типа byte. С точке зрения оптимальности лучше всего использовать конструкцию
Код:
type TRGBtriple = packed record
   case Byte of
      0: (color: TColor);
      1: (value: Cardinal);
      2: (b, g, r: Byte);
      3: (x: array [0 .. 2] of Byte);
   end;
Так компилятор вместо того, чтобы выполнять кучу команд с регистрами будет брать нужный байт генерируя его offset и не понадобятся все эти манипуляции.
Т.е. этот код будет делать примерно это
Код:
mov al, byte ptr [rgbt.color + 2] // r
mov dl, byte ptr [rgbt.color + 1] // g
mov cl, byte ptr [rgbt.color + 0] // b
Вот эти значения вычисляются компилятором на этапе сборки программы (build-time) и сохраняются в ней как есть, а ваши манипуляции с регистрами забирают у программы время исполнения (run-time).

Последний раз редактировалось macomics; 26.08.2022 в 20:53.
macomics вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
одинаковый текст оказался разным HellMercenariess PHP 4 06.08.2012 22:59
Одинаковым данным-одинаковый номер! Любопытная Microsoft Office Excel 16 03.08.2011 10:16
одинаковый код в процедурах jungle Помощь студентам 7 26.11.2008 22:45
Всегда позади и всегда впереди в одном приложении Legat Win Api 4 27.10.2007 15:48