2016-12-26 8 views
1

Поскольку моя основная ОС - это Linux и есть проект на визуальной студии, я решил использовать онлайн-компиляторы для ее достижения. Я нашел this, что было предложено многими. Так вот мой код:Сборка: JA и JB работают некорректно

#include <iostream> 

using namespace std; 
int main(void) { 
float a = 1; 
float b = 20.2; 
float res = 0; 
float res1 = 0; 

_asm { 

    FLD a 
    FCOM b 
    JA midi 
    JMP modi   

    midi: 
    FST res 
    JMP OUT 

    modi: 
    FST res1 
    JMP OUT 


} 
    OUT: 
cout << "res = " << res << endl; 
cout << "res1 = " << res1 << endl; 
return 0; 
} 

Моя цель проста, если a больше что b чем ставить a в res, в противном случае в res1. Но кажется, что у меня есть переменная a, она всегда прыгает на midi, и результат всегда res = whatever is in a. Надеюсь, ты поможешь. Извините, если мои вопросы глупы, я только начал изучать сборку. спасибо :)

P.S
То же самое происходит с JB, но напротив. Он всегда печатает res1 = whatever is in b.

ответ

5

this page От:

РЛЭ сравнивает ST0 с заданным операндом, и устанавливает FPU флаги соответственно.

Но ваш JA midi тестирует ЦП флаги.

Он продолжает:

FCOMI и FCOMIP работают как соответствующие формы РЛЭ и FCOMP, но написать свои результаты непосредственно в CPU регистра флагов, а чем FPU слово состояния, поэтому они могут сразу же следовать инструкциям условного перехода или условного перемещения .

+0

Я получаю сообщение об ошибке сказав 'source_file.cpp (13): ошибка C2414: незаконное количество operands' – Rasty

+0

@Rasty, кажется, что' FCOMI' не может принимать операнд в памяти - загрузить его в регистр. Но у вас есть основная причина, почему ваш код не работает. –

+0

Извините, я не видел вашего ответа, когда я разместил свой файл :(Я держу его с тех пор, как я уже написал его –

4

Это общая ошибка, FCOM не устанавливает флаги в регистре флагов, устанавливает флаги кода условий в ключевом слове FPU.
От Intel manual 2:

Сравнивает содержимое регистра ST(0) и исходного значения и устанавливает флаги кодов услови С0, С2 и С3 в слове состояния FPU в соответствии с результатами (см Приведенная ниже таблица)

Condition codes set by FCOM

Где вы можете увидеть, что C3 берет на себя роль ZF и C1 из CF.

Используйте FCOMI/FUCOMI (и варианты), чтобы соответствующим образом установить флаги.

выполняет неупорядоченное сравнение содержимого регистров ST (0) и ST (я) и устанавливает флаги состояния ZF, PF и CF в EFLAGS регистра в соответствии с результатами [Таблица идентична выше, где C2 является PF].

Разница между FCOMI и FUCOMI, что последний позволяют неупорядоченных операндами, т.е. qNaNs.


В качестве альтернативы вы можете использовать FCOM, но затем переместить коды условий флагам с:

fnstsw ax  ;FP Not-checked STore Status Word in AX 
sahf    ;Store AH into flags 

Intel разработан fnstsw, чтобы быть совместимым с sahf.
Прежние движется С3, С2 и С1 к Бит6, бит2 и бит0, соответственно, AH.
Последние устанавливают флаги как RFLAGS(SF:ZF:0:AF:0:PF:1:CF) ← AH.


Вы можете также testax непосредственно после fnstsw ax, как предложено в разделе 8.3.6.1 Разветвление на x87 FPU Коды состояния из manual 1.

Constants to test AX against after fnstsw for various conditions