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

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

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

enter image description here

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
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, чтобы увидеть, затронуты ли все флаги рассматриваемой инструкцией теста, а затем просмотрите различные проверенные условия, чтобы увидеть, какие из них соответствуют вашему результату.

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