COMISD, не сравнивая должным образом [дубликат]

Почему вы не используете шаблоны функций для этого (C ++)?

  template & lt; class T, int N & gt;  void f (T (& amp; r) [N]) {} int main () {int buf [10];  F (BUF);  }  

EDIT 2:

Теперь у qn появляется C-тег, и тег C ++ удален.

15
задан JustMaximumPower 7 May 2013 в 16:01
поделиться

1 ответ

Все это происходит из тома 2 Руководства разработчика программного обеспечения Intel 64 и IA-32 .

FCOMI устанавливает только некоторые из флагов, которые CMP делает , Ваш код имеет %st(0) == 9 и %st(1) == 10. (Так как это стек, на который они загружены), ссылаясь на таблицу на стр. 3-348 в томе 2А, ​​вы можете видеть, что это так «ST0 & lt; ST (i)», поэтому он очистит ZF и PF и набор CF. Между тем на стр. 3-544 Vol. 2A вы можете прочитать, что JG означает «Переход короткий, если больше (ZF = 0 и SF = OF)». Другими словами, он тестирует значки, переполнения и нулевые флаги, но FCOMI не устанавливает знак или переполнение!

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

+--------------------+---+---+---+
| Comparison results | Z | P | C |
+--------------------+---+---+---+
| ST0 > ST(i)        | 0 | 0 | 0 |
| ST0 < ST(i)        | 0 | 0 | 1 |
| ST0 = ST(i)        | 1 | 0 | 0 |
+--------------------+---+---+---+

Я сделал эту небольшую таблицу, чтобы было легче выяснить:

+--------------+---+---+-----+------------------------------------+
| Test         | Z | C | Jcc | Notes                              |
+--------------+---+---+-----+------------------------------------+
| ST0 < ST(i)  | X | 1 | JB  | ZF will never be set when CF = 1   |
| ST0 <= ST(i) | 1 | 1 | JBE | Either ZF or CF is ok              |
| ST0 == ST(i) | 1 | X | JE  | CF will never be set in this case  |
| ST0 != ST(i) | 0 | X | JNE |                                    |
| ST0 >= ST(i) | X | 0 | JAE | As long as CF is clear we are good |
| ST0 > ST(i)  | 0 | 0 | JA  | Both CF and ZF must be clear       |
+--------------+---+---+-----+------------------------------------+
Legend: X: don't care, 0: clear, 1: set

Иными словами, коды условий соответствуют тем для использования неподписанных сравнений. То же самое происходит, если вы используете FMOVcc.

Если операнд (или оба) с fcomi равен NaN, он устанавливает ZF=1 PF=1 CF=1. (FP-сравнения имеют 4 возможных результата: >, <, == или неупорядоченные). Если вам небезразличен ваш код с помощью NaN, вам может потребоваться дополнительная jp или jnp. Но не всегда: например, ja истинно, только если CF = 0 и ZF = 0, поэтому он не будет принят в неупорядоченном случае. Если вы хотите, чтобы неупорядоченный случай выполнял тот же путь выполнения, что и ниже или равный, тогда вам нужно ja.


Здесь вы должны использовать JA, если хотите, чтобы он печатался ( т.е. if (!(f2 > f1)) { puts("hello"); }) и JBE, если вы этого не сделаете (соответствует if (!(f2 <= f1)) { puts("hello"); }). (Обратите внимание, что это может быть немного запутанным из-за того, что мы печатаем только, если мы не прыгаем).


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

.section    .rodata
msg:    .ascii "Hallo\n\0"
f1:     .float 10.0
f2:     .float 9.0 

.globl main
    .type   main, @function
main:
    flds   f1
    flds   f2
    fcomip
    fstp   %st(0) # to clear stack
    ja     leb # won't jump, jbe will
    pushl  $msg
    call   printf
    addl   $4, %esp
leb:
    pushl  $0
    call   exit
36
ответ дан Peter Cordes 15 August 2018 в 14:51
поделиться
  • 1
    Очень впечатляющий ответ. Отлично. Один незначительный комментарий: противоположность ja - jbe, а не jb. – Ray Toal 14 August 2011 в 18:21
  • 2
    @Ray Toal: Вы абсолютно правы. Несмотря на то, что в этом случае это не будет иметь никакого значения, я изменил этот пример, так как это имеет большее значение. – user786653 14 August 2011 в 18:40
  • 3
    хороший! Большое спасибо! – JustMaximumPower 14 August 2011 в 20:17
Другие вопросы по тегам:

Похожие вопросы: