#include #include uint64_t *bits = (uint64_t[64]) { 0 }; uint64_t top = 0; /* gcc push-bit.c -O3 && objdump -D a.out | less 0000000000001240 : 1240: 48 8b 05 f1 2d 00 00 mov 0x2df1(%rip),%rax # 4038 1247: 48 89 fa mov %rdi,%rdx 124a: 48 c1 ea 06 shr $0x6,%rdx 124e: 48 8b 04 d0 mov (%rax,%rdx,8),%rax 1252: 48 0f a3 f8 bt %rdi,%rax 1256: 0f 92 c0 setb %al 1259: 0f b6 c0 movzbl %al,%eax 125c: c3 ret 125d: 0f 1f 00 nopl (%rax) */ uint64_t get_bit (uint64_t const addr) { uint64_t const shift = addr & (uint64_t) 0b111111; uint64_t const index = addr >> 6; return (bits[index] >> shift) & 1; } /* gcc push-bit.c -O3 && objdump -D a.out | less 0000000000001260 : 1260: 48 8b 05 d1 2d 00 00 mov 0x2dd1(%rip),%rax # 4038 1267: 48 89 fa mov %rdi,%rdx 126a: 48 89 f9 mov %rdi,%rcx 126d: 83 e6 01 and $0x1,%esi 1270: 48 c1 ea 06 shr $0x6,%rdx 1274: 48 d3 e6 shl %cl,%rsi 1277: 48 8d 14 d0 lea (%rax,%rdx,8),%rdx 127b: 48 c7 c0 fe ff ff ff mov $0xfffffffffffffffe,%rax 1282: 48 d3 c0 rol %cl,%rax 1285: 48 23 02 and (%rdx),%rax 1288: 48 09 f0 or %rsi,%rax 128b: 48 89 02 mov %rax,(%rdx) 128e: c3 ret 128f: 90 nop */ void set_bit (uint64_t const addr, uint64_t const value) { uint64_t const shift = addr & (uint64_t) 0b111111; uint64_t const index = addr >> 6; bits[index] &= ~((uint64_t) 1 << shift); // clear bits[index] |= ((value & 1) << shift); // set } void push_bit (uint64_t const value) { set_bit(top, value); top++; } void print_bits (void) { printf(":: "); for (uint64_t i = 0; i < top; i++) { putchar(get_bit(i) ? '1' : '0'); if (i > 0 && (i + 1) % 4 == 0) { putchar('.'); } } putchar('\n'); } int main (int argc, char const **argv) { printf("[%s, Press Ctrl+D or Ctrl+C to Quit]\n", argv[0]); printf("[Type 0 or 1 to push a bit, Type P to print stack]\n"); while (!feof(stdin)) { int const c = getchar(); switch (c) { break; case '0': push_bit(0); break; case '1': push_bit(1); break; case 'p': print_bits(); } } return 0; }