Nano Hash - криптовалюты, майнинг, программирование

Считается ли плохой практикой использование регистра флагов в качестве логического возвращаемого значения?

Я пишу некоторые процедуры на ассемблере x86, которые модифицируют ZF как средство для возврата логических значений, поэтому я могу сделать что-то вроде этого:

call is_value_correct
jz not_correct

Мне интересно, считается ли это плохой практикой, поскольку в некоторых стандартах кодирования говорится, что простые значения должны возвращаться в регистр AX.


  • Если вам не нужно следовать соглашению о вызовах, а вызывающие программы написаны на ассемблере, то я думаю, что это вполне приемлемо. Службы BIOS сделали это много, и я нашел это очень полезным (они избавили меня от теста). 22.01.2018
  • нет, это не плохая практика. Некоторое время назад даже операционные системы (например, CP/M или DOS) возвращали ошибки во флагах (например, функция DOS 21h 03ch указывает на ошибку в CarryFlag) 22.01.2018
  • пока вы просто вызываете эту функцию внутри своего кода, все в порядке, библиотечные функции обычно программируются на языках высокого уровня и для них, где у вас обычно есть только одно возвращаемое значение, обычно в eax/rax. Вы также можете использовать переносной флаг. 22.01.2018
  • gcc встроенная сборка может использовать регистры флагов для возврата значений (начиная с gcc 6, я полагаю). 22.01.2018
  • @EOF, хотя с немного меньшей эффективностью вы могли бы сделать это вручную в более ранних GCC, установив ограничение вывода на значение одного из флагов. 22.01.2018

Ответы:


1

Да, сделайте это, если ваш код будет работать быстрее и/или в целом станет меньше.

Одним из преимуществ ручного написания на ассемблере является возможность использовать пользовательские функции соглашений о вызовах, даже если они не являются частными вспомогательными функциями или макросами. Это включает в себя возможность «возвращать» несколько значений в разных регистрах и в основном делать все, что вы хотите.

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

# inputs:   foo in EAX (zero-extended into RAX), bar in EDI
# pre-requisites: DF=0
# clobbers: RCX, RDX, AL (but not the rest of EAX)
# returns:  AL = something,  ZF = something else
my_func:
   ...
   setc al
   ...
   something that sets ZF
   ret

Если вы готовы пожертвовать эффективностью ради стиля или удобочитаемости, вам, вероятно, не стоит писать на ассемблере в первую очередь в 2018 году, когда компиляторы в большинстве случаев способны генерировать хороший ассемблер, и вам редко нужно писать собственный загрузочный код. сектор или что-то еще. (т. е. производительность является основным вариантом использования, оставленным для написанного от руки ассемблера, и это уместно только в том случае, если вы делаете все возможное для производительности.)

Да, написанный от руки ассемблер может превратиться в нечитаемый/неподдающийся сопровождению беспорядок, но если все сделано аккуратно, когда он имеет разумное семантическое значение, эта оптимизация не сделает ваш код беспорядочным.


Для этого даже есть прецедент: системные вызовы x86-64 OS X использовать CF в качестве статуса ошибки/отсутствия ошибки, отдельно от возвращаемого значения rax. В отличие от Linux, где ошибки обозначаются возвращаемыми значениями RAX от -4095 до -1, хотя в остальном они используют одно и то же соглашение x86-64 System V ABI/вызовов.

Некоторые системные вызовы DOS int 0x21 и функции PC BIOS int 0x10 имеют аналогичную систему возврата флагов. Он позволяет вызывающей стороне переходить при ошибке, поэтому экономит размер кода (тест или cmp) и позволяет избежать необходимости внутриполосной сигнализации об ошибках.

22.01.2018
  • Интересно, почему ABI просто не таковы, чтобы возврат _Bool выполнялся путем установки флага. Использование регистра для возврата _Bool кажется мне пустой тратой времени. 27.05.2019
  • @PSkocik: Было бы интересно. Многим функциям требуется add или sub для очистки фрейма стека, но они могут LEA. Или отложите фактическую операцию установки флага до момента возврата после запуска деструкторов. Но самая большая проблема: какой флаг вы бы выбрали? CF — очевидный выбор (потому что для его использования есть специальные инструкции, например adc / sbb), и некоторые специальные инструкции задают его (bt / bts и т. д., rdrand). Но если ваш _Bool поступает из ZF из такой инструкции, как bsr или bsr, или сравнения ==, или сравнения SF + OF со знаком, вы, вероятно. нужен сете/ле + смп. 27.05.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

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

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..