Последняя активность 3 weeks ago

push-bit.c Исходник Playground
1
2#include <stdio.h>
3#include <stdint.h>
4
5uint64_t *bits = (uint64_t[64]) { 0 };
6uint64_t top = 0;
7
8/* gcc push-bit.c -O3 && objdump -D a.out | less
90000000000001240 <get_bit>:
10 1240: 48 8b 05 f1 2d 00 00 mov 0x2df1(%rip),%rax # 4038 <bits>
11 1247: 48 89 fa mov %rdi,%rdx
12 124a: 48 c1 ea 06 shr $0x6,%rdx
13 124e: 48 8b 04 d0 mov (%rax,%rdx,8),%rax
14 1252: 48 0f a3 f8 bt %rdi,%rax
15 1256: 0f 92 c0 setb %al
16 1259: 0f b6 c0 movzbl %al,%eax
17 125c: c3 ret
18 125d: 0f 1f 00 nopl (%rax)
19*/
20
21uint64_t
22get_bit (uint64_t const addr) {
23 uint64_t const shift = addr & (uint64_t) 0b111111;
24 uint64_t const index = addr >> 6;
25
26 return (bits[index] >> shift) & 1;
27}
28
29/* gcc push-bit.c -O3 && objdump -D a.out | less
300000000000001260 <set_bit>:
31 1260: 48 8b 05 d1 2d 00 00 mov 0x2dd1(%rip),%rax # 4038 <bits>
32 1267: 48 89 fa mov %rdi,%rdx
33 126a: 48 89 f9 mov %rdi,%rcx
34 126d: 83 e6 01 and $0x1,%esi
35 1270: 48 c1 ea 06 shr $0x6,%rdx
36 1274: 48 d3 e6 shl %cl,%rsi
37 1277: 48 8d 14 d0 lea (%rax,%rdx,8),%rdx
38 127b: 48 c7 c0 fe ff ff ff mov $0xfffffffffffffffe,%rax
39 1282: 48 d3 c0 rol %cl,%rax
40 1285: 48 23 02 and (%rdx),%rax
41 1288: 48 09 f0 or %rsi,%rax
42 128b: 48 89 02 mov %rax,(%rdx)
43 128e: c3 ret
44 128f: 90 nop
45*/
46
47void
48set_bit (uint64_t const addr, uint64_t const value) {
49 uint64_t const shift = addr & (uint64_t) 0b111111;
50 uint64_t const index = addr >> 6;
51
52 bits[index] &= ~((uint64_t) 1 << shift); // clear
53 bits[index] |= ((value & 1) << shift); // set
54}
55
56void
57push_bit (uint64_t const value) {
58 set_bit(top, value);
59 top++;
60}
61
62void
63print_bits (void) {
64 printf(":: ");
65 for (uint64_t i = 0; i < top; i++) {
66 putchar(get_bit(i) ? '1' : '0');
67 if (i > 0 && (i + 1) % 4 == 0) {
68 putchar('.');
69 }
70 }
71 putchar('\n');
72}
73
74int
75main (int argc, char const **argv) {
76 printf("[%s, Press Ctrl+D or Ctrl+C to Quit]\n", argv[0]);
77 printf("[Type 0 or 1 to push a bit, Type P to print stack]\n");
78 while (!feof(stdin)) {
79 int const c = getchar();
80 switch (c) {
81 break; case '0': push_bit(0);
82 break; case '1': push_bit(1);
83 break; case 'p': print_bits();
84 }
85 }
86 return 0;
87}
88