В попытке выставить некоторые инструкции 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