Почему вы не используете шаблоны функций для этого (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 ++ удален.
Все это происходит из тома 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
ja
-jbe
, а неjb
. – Ray Toal 14 August 2011 в 18:21