1 #include <cstdint> 2 #include <mutex> 3 #include <thread> 4 5 std::mutex t1_mutex, t2_mutex; 6 7 struct test_data { 8 uint32_t eax; 9 uint32_t ebx; 10 11 struct alignas(16) { 12 uint64_t mantissa; 13 uint16_t sign_exp; 14 } st0; 15 }; 16 17 void t_func(std::mutex &t_mutex, const test_data &t_data) { 18 std::lock_guard<std::mutex> t_lock(t_mutex); 19 20 asm volatile( 21 "finit\t\n" 22 "fldt %2\t\n" 23 "int3\n\t" 24 : 25 : "a"(t_data.eax), "b"(t_data.ebx), "m"(t_data.st0) 26 : "st" 27 ); 28 } 29 30 int main() { 31 test_data t1_data = { 32 .eax = 0x05060708, 33 .ebx = 0x15161718, 34 .st0 = {0x8070605040302010, 0x4000}, 35 }; 36 test_data t2_data = { 37 .eax = 0x25262728, 38 .ebx = 0x35363738, 39 .st0 = {0x8171615141312111, 0xc000}, 40 }; 41 42 // block both threads from proceeding 43 std::unique_lock<std::mutex> m1_lock(t1_mutex); 44 std::unique_lock<std::mutex> m2_lock(t2_mutex); 45 46 // start both threads 47 std::thread t1(t_func, std::ref(t1_mutex), std::ref(t1_data)); 48 std::thread t2(t_func, std::ref(t2_mutex), std::ref(t2_data)); 49 50 // release lock on thread 1 to make it interrupt the program 51 m1_lock.unlock(); 52 // wait for thread 1 to finish 53 t1.join(); 54 55 // release lock on thread 2 56 m2_lock.unlock(); 57 // wait for thread 2 to finish 58 t2.join(); 59 60 return 0; 61 } 62