В попытке выставить некоторые инструкции cmov на ядре intel 2, работающем под управлением Windows 7, я написал код ниже. Все, что он делает, это взять строку из консоли в качестве ввода, применить некоторые операции сдвига для генерации случайного семени, а затем передать это семя на srand для генерации небольшого массива псевдослучайных чисел. Затем псевдослучайные числа вычисляются для того, удовлетворяют ли они предикатной функции (более произвольная битовая головоломка) и выводят "*" или "_". Цель эксперимента - генерировать инструкции cmov, но, как вы можете видеть в разборке ниже, их нет.
Любые советы о том, как изменить код или флагов, чтобы они были сгенерированы?
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
bool blackBoxPredicate( const unsigned int& ubref ) {
   return ((ubref << 6) ^ (ubref >> 2) ^ (~ubref << 2)) % 15 == 0;
}
int main() {
   const unsigned int NUM_RINTS = 32;
   unsigned int randomSeed = 1;
   unsigned int popCount = 0;
   unsigned int * rintArray = new unsigned int[NUM_RINTS];
   std::string userString;
   std::cout << "input a string to use as a random seed: ";
   std::cin >> userString;
   std::for_each( 
      userString.begin(), 
      userString.end(), 
      [&randomSeed] (char c) {
         randomSeed = (randomSeed * c) ^ (randomSeed << (c % 7));
   });
   std::cout << "seed computed: " << randomSeed << std::endl;
   srand(randomSeed);
   for( int i = 0; i < NUM_RINTS; ++i ) {
      rintArray[i] = static_cast<unsigned int> (rand());
      bool pr = blackBoxPredicate(rintArray[i]);
      popCount = (pr) ? (popCount+1) : (popCount);
      std::cout << ((pr) ? ('*') : ('_')) << " ";
   }
   std::cout << std::endl;
   delete rintArray;
   return 0;
}
И использовал этот make файл для его создания:
OUT=cmov_test.exe
ASM_OUT=cmov_test.asm
OBJ_OUT=cmov_test.obj
SRC=cmov_test.cpp
THIS=makefile
CXXFLAGS=/nologo /EHsc /arch:SSE2 /Ox /W3
$(OUT): $(SRC) $(THIS)
   cl $(SRC) $(CXXFLAGS) /FAscu /Fo$(OBJ_OUT) /Fa$(ASM_OUT) /Fe$(OUT)
clean:
   erase $(OUT) $(ASM_OUT) $(OBJ_OUT)
И все же, когда я пошел посмотреть, были ли какие-либо из них созданы, я увидел, что компиляторы microsoft создали следующую сборку для этого последнего цикла:
; 34   :       popCount = (pr) ? (popCount+1) : (popCount);
; 35   :       
; 36   :       std::cout << ((pr) ? ('*') : ('_')) << " ";
  00145 68 00 00 00 00   push    OFFSET $SG30347
  0014a 85 d2        test    edx, edx
  0014c 0f 94 c0     sete    al
  0014f f6 d8        neg     al
  00151 1a c0        sbb     al, al
  00153 24 cb        and     al, -53            ; ffffffcbH
  00155 04 5f        add     al, 95         ; 0000005fH
  00157 0f b6 d0     movzx   edx, al
  0015a 52       push    edx
  0015b 68 00 00 00 00   push    OFFSET [email protected]@@[email protected][email protected]@[email protected]@@[email protected] ; std::cout
  00160 e8 00 00 00 00   call    [email protected]@[email protected]@@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@[email protected] ; std::operator<<<std::char_traits<char> >
  00165 83 c4 08     add     esp, 8
  00168 50       push    eax
  00169 e8 00 00 00 00   call    [email protected]@[email protected]@@[email protected]@[email protected][email protected]@[email protected]@@[email protected]@[email protected] ; std::operator<<<std::char_traits<char> >
  0016e 46       inc     esi
  0016f 83 c4 08     add     esp, 8
  00172 83 fe 20     cmp     esi, 32            ; 00000020H
  00175 72 a9        jb  SHORT [email protected]
Для вашей справки, вот мои строки cpu id и версия компилятора.
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 58 Stepping 9, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=3a09
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
