push-bit.c
· 2.9 KiB · C
Исходник
Playground
#include <stdio.h>
#include <stdint.h>
uint64_t *bits = (uint64_t[64]) { 0 };
uint64_t top = 0;
/* gcc push-bit.c -O3 && objdump -D a.out | less
0000000000001240 <get_bit>:
1240: 48 8b 05 f1 2d 00 00 mov 0x2df1(%rip),%rax # 4038 <bits>
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 <set_bit>:
1260: 48 8b 05 d1 2d 00 00 mov 0x2dd1(%rip),%rax # 4038 <bits>
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;
}
| 1 | |
| 2 | #include <stdio.h> |
| 3 | #include <stdint.h> |
| 4 | |
| 5 | uint64_t *bits = (uint64_t[64]) { 0 }; |
| 6 | uint64_t top = 0; |
| 7 | |
| 8 | /* gcc push-bit.c -O3 && objdump -D a.out | less |
| 9 | 0000000000001240 <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 | |
| 21 | uint64_t |
| 22 | get_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 |
| 30 | 0000000000001260 <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 | |
| 47 | void |
| 48 | set_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 | |
| 56 | void |
| 57 | push_bit (uint64_t const value) { |
| 58 | set_bit(top, value); |
| 59 | top++; |
| 60 | } |
| 61 | |
| 62 | void |
| 63 | print_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 | |
| 74 | int |
| 75 | main (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 |