О сборке условного кода регистра - PullRequest
3 голосов
/ 26 апреля 2009

предположим, что мы используем addl инструкция для выполнения эквивалент выражения C "t = a + b", где a, b, t - переменные типа int , тогда условный код будет установлен в соответствии со следующим C выражение:

CF: (без знака t) <(без знака a) переполнение без знака </p>

ZF: (t == 0) ноль

SF: (t <0) отрицательный </p>

OF: (a <0 == b <0) && (t <0! = A <0) переполнение со знаком </p>

Извлечено из учебника по компьютерной системе.

  • CF - флаг переноса.
  • ZF - нулевой флаг.
  • SF - флаг-знак.
  • OF - флаг переполнения.

Я не могу понять, почему эти выражения C имеют эффект, упомянутый выше. Например, почему выражение (t <0) будет устанавливать флаг SF ?? t <0 является либо истиной, либо ложью (поскольку в учебнике указан только тип этих переменных), но почему был установлен флаг знака? Я действительно запутался, пожалуйста, помогите .. спасибо! </p>

Ответы [ 4 ]

1 голос
/ 26 апреля 2009

CF, ZF, SF и OF являются единичными битами в регистре CC (код условия). Есть и другие биты, которые устанавливаются при других условиях. Всякий раз, когда ЦП выполняет определенные инструкции (включая add и sub), он устанавливает эти биты в соответствии с результатом операции. Инструкции cmp и test действуют идентично инструкциям sub и and соответственно, за исключением того, что они полностью отбрасывают результат, и единственным выходом являются флаги условий.

Предположим, у нас есть следующий код C:

int a, b;
...
a -= b;
if(a < 0)
{
    // stuff...
}

Наивный компилятор может скомпилировать это так:

    ; Suppose a is in the eax register and b is in the edx register
    sub %eax, %edx  ; subtract b from a, store result in a
    cmp $0, %eax    ; compare a to 0
    jl end_of_stuff ; if a < 0, goto end_of_stuff
    ; code for stuff goes here
end_of_stuff:
    ; code after if block goes here

Более умный компилятор, однако, поймет, что инструкция sub уже устанавливает коды условий, поэтому он может скомпилировать ее следующим образом:

    sub %eax, %edx
    jl end_of_stuff   ; if a < 0, goto end_of_stuff
    ; code for stuff goes here
end_of_stuff:
    ; code after if block goes here

Обратите внимание, что инструкция jl (переход, если меньше, чем) выполняет переход, если и только если SF ≠ OF. То есть он скачет, если результат отрицательный и переполнения не произошло, или если результат положительный и переполнение произошло. Это необходимо для обеспечения получения правильного результата при переполнении разницы (например, сравнение INT_MIN с INT_MAX).

1 голос
/ 26 апреля 2009

ЦП устанавливает эти флаги после выполнения арифметических операций. То, что вы называете «выражениями C», на самом деле является описанием условий, при которых устанавливаются различные флаги ЦП. Например, если результат равен 0, будет установлен нулевой флаг.

Или для решения конкретного вопроса, следующего:

SF: (t <0) отрицательный </p>

означает, что если результат арифметической операции отрицательный, ЦП устанавливает флаг SF. 'T <0' не является выражением C - оно просто объясняет, когда установлен флаг. </p>

Флаги можно использовать позже для потока управления, используя инструкции, которые условно переходят на значение флагов.

0 голосов
/ 26 апреля 2009

Это наоборот. Когда вы пишете t <0 в C, это компилируется в ветвь, которая зависит от флага S (также часто называемого N для отрицательного значения). В процессоре флаг S просто копируется из старшего бита результата. </p>

0 голосов
/ 26 апреля 2009

Это все еще не ясный вопрос, но вот что я почерпнул. Я думаю, что вы хотите знать, "почему установлен флаг флага (SF), когда все, что я делаю, это t = a + b?" Я отвечу на это.

Простой ответ заключается в том, что тип 'int' C подписан, вы должны сказать 'unsigned int', чтобы получить версию без знака. Следовательно, в ситуации t = a + b все эти переменные подписаны. Теперь, почему флаг может быть установлен:

let a = 5, b = -10
t = a+b
t = 5 - 10
t = -5 (SF will be set because of the negative)

let a = 5, b = 10
t = a+b
t = 5 + 10
t = 15 (SF will not be set because of the positive)

Если вы хотите узнать больше о знаках на числах в том виде, в каком они указаны в C, то я бы посоветовал вам взглянуть на Единственное дополнение и Двойное дополнение.

Надеюсь, это ответит на вопрос.

...