Условный переход и флаговый бит в сборке

Я изучаю ассемблер. Я понимаю, что операция CMP R1 R2 устанавливает биты флагов (перенос, переполнение, ноль, знак и т. д.) В соответствии с результатом R1-R2. И я понимаю, что инструкции условного перехода JX, такие как JA, JBE, следуют после CMP. Если условие битов флага совпадает, инструкция JX заставляет IP переходить на указанный адрес.

Чего я никогда не понимал, так это «Испытанные условия» на прикрепленной мною картинке.

Условный переход и флаговый бит в сборке

CMP R1 R2

JAE где-то

Приведенный выше код, очевидно, переходит куда-нибудь, если R1 больше или равно R2. Если R1 = 0111 и R2 = 0110, JAE перескочит куда-нибудь. В таком случае,

R1-R2 = 0111-0110 = 0111+1010 = 10001 = 0001 with carry bit set

обратите внимание, что я добавил 2 дополнения к 0110 вместо вычитания 0110, потому что микроконтроллеры вычисляют таким образом, как я знаю

Но в учебнике сказано, что JAE будет прыгать, если флаг переноса равен 0. Мои вычисления показывают, что C = 1, если R1 больше, чем R2. Другие примеры показывают, что C = 1, если R1 больше R2. Нет проблем со знаком.

Так что плохого в «испытанных условиях»?

Ничего такого. Если R1 больше или равно R2, нет необходимости заимствовать при вычитании R2 из R1, поэтому бит переноса очищен.

David Hoelzer 11.04.2018 12:36

Почему вы вычисляете 111-110, используя сложение и отрицание второго аргумента, и вычитаете состояние флагов из этого сложения? CF и другие флаги относятся к вычитанию, не имеет значения, выполняется ли это внутри путем добавления отрицательного значения, а 111-110 равно 1 с CF = 0, ZF = 0, PF = 0 и т. д.

Ped7g 11.04.2018 12:45

@ Ped7g Насколько я знаю, в микропроцессоре нет вычитателя. Таким образом, требуется дополнение до 2 и добавление его сумматором.

hskim 11.04.2018 12:55

Вычитание - это не то же самое, что сложение дополнения до 2, потому что результирующие флаги, как вы видели, отличаются.

interjay 11.04.2018 13:06

@hskim, к сожалению, я не изучал схемы процессоров 8086 или новее x86, поэтому я не знаю, есть ли у них только сумматор, но если они есть, вокруг него должна быть какая-то «обертка» вычитателя, чтобы исправить флаги после добавления должны быть установлены так, как их определяет инструкция sub. Я могу просто заверить вас, что флаги имеют отношение к вычитанию, то есть CF = did_borrow и 111-110 не нужно заимствовать -> CF = 0. Понятия не имею, как это реализовано в транзисторах.

Ped7g 11.04.2018 14:25

При использовании jae числа рассматриваются как беззнаковые. Таким образом, добавление двух дополнений к числу не эквивалентно вычитанию исходного числа. Вот почему результаты флагов разные. В вашем примере 7-6 - это не то же самое, что 7 + 10 (это 10, а не «-6»).

lurker 11.04.2018 16:19

вычитание реализовано в логике как сложение с инвертированным вторым операндом и инвертированным переносом в lsb. Независимо от того, инвертируется ли выполнение msbit и называется заимствованием, зависит от конструкции архитектуры, некоторые делают то же самое, некоторые - нет. Все флаги можно правильно разрешить. a = b + c = b + (-c) тождество было истинным в математике задолго до электричества, гораздо меньше транзисторов, гораздо меньше двоичной логики и тем более двоичного дополнения.

old_timer 11.04.2018 17:16

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

old_timer 11.04.2018 17:19

а не многие из этих комбинаций, которые вам действительно не нужны.

old_timer 11.04.2018 17:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
2 032
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это вычитание

R1-R2 = 0111-0110 

реализуется так в логике

     1
  0111
+ 1001
========

закончить математику

 11111
  0111
+ 1001
========
  0001

поэтому выполнение (беззнаковое переполнение) равно 1, подписанное переполнение равно 0, так как перенос и выполнение до совпадения msbit также может определить это из msbit операндов и результата. если msbit операндов совпадают друг с другом, но msbit результата не совпадает с msbit, то подписанное переполнение.

не ноль, поэтому флаг z будет равен 0, а бит msbit не установлен, поэтому флаг n не будет установлен.

следующий вопрос: выполняет ли эта архитектура инвертирования флаг переноса при вычитании, делая его заимствованным, или они переносят его прямо?

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

Другие вопросы по теме