Сборка: JA и JB работают некорректно

Поскольку моей основной ОС является linux, и у меня есть проект на visual studio, я решил использовать для этого онлайновые компиляторы. я нашел этот что было предложено многими. Итак, вот мой код:

#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,

1

Решение

От эта страница:

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

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

Это продолжается:

FCOMI и FCOMIP работают как соответствующие формы FCOM и FCOMP,
но напишите свои результаты прямо в ЦПУ флаги прописываются скорее
чем FPU статусное слово, чтобы за ним сразу могли следовать
инструкции условного перехода или условного перемещения.

5

Другие решения

Это распространенная ошибка, FCOM не устанавливает флаги в регистре флагов, он устанавливает флаги кода состояния в слове состояния FPU.
От Руководство Intel 2:

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

Коды условий, установленные FCOM

Где вы можете увидеть это C3 берет на себя роль ZF а также С1 из CF.

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

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

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


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

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

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


Вы также можете test ax сразу после fnstsw ax как предложено в разделе 8.3.6.1. Ветвление кодов состояния x87 FPU из руководство 1.

Константы для проверки AX после fnstsw для различных условий

4

По вопросам рекламы [email protected]