1 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <assert.h> 5 6 typedef unsigned int UInt; 7 8 /* Given a word, do bt/bts/btr/btc on bits 0, 1, 2 and 3 of it, and 9 also reconstruct the original bits 0, 1, 2, 3 by looking at the 10 carry flag. Returned result has mashed bits 0-3 at the bottom and 11 the reconstructed original bits 0-3 as 4-7. */ 12 UInt mash_reg_L ( UInt orig ) 13 { 14 UInt reconstructed, mashed; 15 __asm__ __volatile__ ( 16 "movl %2, %%edx\n\t" 17 "" 18 "movl $0, %%eax\n\t" 19 "\n\t" 20 "btl $0, %%edx\n\t" 21 "setb %%cl\n\t" 22 "movzbl %%cl, %%ecx\n\t" 23 "orl %%ecx, %%eax\n\t" 24 "\n\t" 25 "btsl $1, %%edx\n\t" 26 "setb %%cl\n\t" 27 "movzbl %%cl, %%ecx\n\t" 28 "shll $1, %%ecx\n\t" 29 "orl %%ecx, %%eax\n\t" 30 "\n\t" 31 "btrl $2, %%edx\n\t" 32 "setb %%cl\n\t" 33 "movzbl %%cl, %%ecx\n\t" 34 "shll $2, %%ecx\n\t" 35 "orl %%ecx, %%eax\n\t" 36 "\n\t" 37 "btcl $3, %%edx\n\t" 38 "setb %%cl\n\t" 39 "movzbl %%cl, %%ecx\n\t" 40 "shll $3, %%ecx\n\t" 41 "orl %%ecx, %%eax\n\t" 42 "\n\t" 43 "movl %%eax, %0\n\t" 44 "movl %%edx, %1" 45 46 : "=r" (reconstructed), "=r" (mashed) 47 : "r" (orig) 48 : "eax", "ecx", "edx", "cc"); 49 return (mashed & 0xF) | ((reconstructed & 0xF) << 4); 50 } 51 52 53 54 55 UInt mash_mem_L ( UInt* origp ) 56 { 57 UInt reconstructed, mashed; 58 __asm__ __volatile__ ( 59 "movl %2, %%edx\n\t" 60 "" 61 "movl $0, %%eax\n\t" 62 "\n\t" 63 "btl $0, (%%edx)\n\t" 64 "setb %%cl\n\t" 65 "movzbl %%cl, %%ecx\n\t" 66 "orl %%ecx, %%eax\n\t" 67 "\n\t" 68 "btsl $1, (%%edx)\n\t" 69 "setb %%cl\n\t" 70 "movzbl %%cl, %%ecx\n\t" 71 "shll $1, %%ecx\n\t" 72 "orl %%ecx, %%eax\n\t" 73 "\n\t" 74 "btrl $2, (%%edx)\n\t" 75 "setb %%cl\n\t" 76 "movzbl %%cl, %%ecx\n\t" 77 "shll $2, %%ecx\n\t" 78 "orl %%ecx, %%eax\n\t" 79 "\n\t" 80 "btcl $3, (%%edx)\n\t" 81 "setb %%cl\n\t" 82 "movzbl %%cl, %%ecx\n\t" 83 "shll $3, %%ecx\n\t" 84 "orl %%ecx, %%eax\n\t" 85 "\n\t" 86 "movl %%eax, %0\n\t" 87 "movl (%%edx), %1" 88 89 : "=r" (reconstructed), "=r" (mashed) 90 : "r" (origp) 91 : "eax", "ecx", "edx", "cc"); 92 return (mashed & 0xF) | ((reconstructed & 0xF) << 4); 93 } 94 95 96 97 UInt mash_reg_W ( UInt orig ) 98 { 99 UInt reconstructed, mashed; 100 __asm__ __volatile__ ( 101 "movl %2, %%edx\n\t" 102 "" 103 "movl $0, %%eax\n\t" 104 "\n\t" 105 "btw $0, %%dx\n\t" 106 "setb %%cl\n\t" 107 "movzbl %%cl, %%ecx\n\t" 108 "orl %%ecx, %%eax\n\t" 109 "\n\t" 110 "btsw $1, %%dx\n\t" 111 "setb %%cl\n\t" 112 "movzbl %%cl, %%ecx\n\t" 113 "shll $1, %%ecx\n\t" 114 "orl %%ecx, %%eax\n\t" 115 "\n\t" 116 "btrw $2, %%dx\n\t" 117 "setb %%cl\n\t" 118 "movzbl %%cl, %%ecx\n\t" 119 "shll $2, %%ecx\n\t" 120 "orl %%ecx, %%eax\n\t" 121 "\n\t" 122 "btcw $3, %%dx\n\t" 123 "setb %%cl\n\t" 124 "movzbl %%cl, %%ecx\n\t" 125 "shll $3, %%ecx\n\t" 126 "orl %%ecx, %%eax\n\t" 127 "\n\t" 128 "movl %%eax, %0\n\t" 129 "movl %%edx, %1" 130 131 : "=r" (reconstructed), "=r" (mashed) 132 : "r" (orig) 133 : "eax", "ecx", "edx", "cc"); 134 return (mashed & 0xF) | ((reconstructed & 0xF) << 4); 135 } 136 137 138 139 140 int main ( void ) 141 { 142 int i, ii; 143 for (i = 0; i < 0x10; i++) { 144 ii = i; 145 printf("0x%x -> 0x%2x 0x%2x 0x%2x\n", i, 146 mash_reg_L(i), mash_mem_L(&ii), mash_reg_W(i)); 147 } 148 return 1; 149 } 150 151