# Jserv-Linux-kernel Week1 ###### tags: `linux2020` `C` ### Course Instructions ### Bitwise operations(my practice) #### Hex to Binary coversion > 0xFF = 0b11111111 >推導過程: \begin{split} 0xFF &= 16*16^0 \\ &= 16(1*2^3+1*2^2+1*2^1+1*2^0)+16(0*2^3+0*2^2+0*2^1+0*2^0) \\ &= 2^4(1*2^3+1*2^2+1*2^1+1*2^0)+16 \\ &= (1*2^7 + 1*2^6 + 1*2^15 + 1*2^4) + (1*2^3 + 1*2^2 + 1*2^1 + 1*2^0) \\ &= 1*2^7 + 1*2^6 + 1*2^15 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0 \\ &= 0b11111111 \end{split} #### Setting and Clearing a bit >Code: (with my comment and note) ```c=1 /* * created by unknowntpo at 2020.1.14(Tue) * @ ref: https://hackmd.io/@sysprog/By0MltO_m?type=view * @ title: Jserv linux核心 bitwise operation * Setting and Clearing a Bit. * */ #include <stdio.h> #include <stdbool.h> /* * @ Function: binary * @ convert the Decimal to Binary. * if n = 256 * n in binary is n = 0b100000000 * the initial i is i = 0b100000000 * --> when first loop end, the printed value is 1. */ void binary(unsigned int n) { for (int i=256; i>0; i/=2) { // i/=2 means right shift 1 bit if (n & i) printf(" 1"); else printf(" 0"); } printf("\n"); } /* * @ Function: getBit * @ get the current bit, which location is specified by the index. * * */ bool getBit(int n, int index){ return ((n & (1 << index)) >0); } /* * @ Function: setBit * @ set the current bit to 1. */ int setBit(int n, int index, bool b) { if(b) return (n | (1 << index)); // if b = true, just set the 'index'-th bit. int mask = ~(1 << index); return n & mask; // if b = false, the mask is used to unset the 'index'-th bit. } int main() { int num = 16, index; printf("input\n"); for (int i = 7; i >=0; i--) printf("%d ", getBit(num,i)); printf("\n"); /* set bit */ index = 6; printf("# Setting %d-th bit\n", index); num = setBit(num, index, true); // "" for (int i = 7; i >= 0; i--) printf("%d ", getBit(num,i)); printf("\n"); /* unset (clear) bit */ index = 4; printf("# Clearing %d-th bit\n", index); num = setBit(num, index, false); // false means we want to clear the bit. for (int i = 7; i >= 0; i--) printf("%d ", getBit(num,i)); printf("\n"); } ``` >Output: ``` input 0 0 0 1 0 0 0 0 # Setting 6-th bit 0 1 0 1 0 0 0 0 # Clearing 4-th bit 0 1 0 0 0 0 0 0 ``` ### 2018q1 考古題 #### 測驗`1`: > 試著證明: > 三的倍數,皆為 “在奇數位與偶數位上”,“1的個數差” 為 0 或 3n (n為整數) :::info ```Tips1:```解不出答案的時候,就把數字代入程式碼中,手動模擬電腦的行為,答案就會慢慢浮現, 脈絡也會更清晰。 ```Tips2:```手抄程式碼雖然慢,但是對我來說,更能深刻的把電腦的行為與邏輯刻在腦海中。 ::: :::success >>使用gdb工具發現自己的手寫筆記忘記抄錄while loop 的下括號, >>導致n=4代入推導之後結果=1 (應該要是0才對) >> GDB-debugger ``` (gdb) step Breakpoint 1, isMultN (n=1) at quiz.c:12 12 int odd_c =0, even_c =0; /* variables to cound odd and even SET bits */ (gdb) step Breakpoint 2, isMultN (n=1) at quiz.c:14 14 if (n == 0) // return true if difference is 0; (gdb) print n $16 = 1 (gdb) step 16 if (n == 1) (gdb) step 17 return 0; (gdb) step 31 } (gdb) step main () at quiz.c:41 41 printf("test num=%d, result=%d\n",i,result); (gdb) step __printf (format=0xaaaaaaaaa940 "test num=%d, result=%d\n") at printf.c:33 33 printf.c: No such file or directory. (gdb) step __vfprintf_internal (s=0xfffff7fc6550 <_IO_2_1_stdout_>, format=0xaaaaaaaaa940 "test num=%d, result=%d\n", ap=..., mode_flags=mode_flags@entry=0) at vfprintf-internal.c:1328 1328 vfprintf-internal.c: No such file or directory. (gdb) step 1332 in vfprintf-internal.c (gdb) step 1343 in vfprintf-internal.c (gdb) step 1354 in vfprintf-internal.c (gdb) step 1365 in vfprintf-internal.c (gdb) continue Continuing. test num=4, result=0 [Inferior 1 (process 8578) exited normally] (gdb) continue The program is not being run. (gdb) quit(gdb) step Breakpoint 1, isMultN (n=1) at quiz.c:12 12 int odd_c =0, even_c =0; /* variables to cound odd and even SET bits */ (gdb) step Breakpoint 2, isMultN (n=1) at quiz.c:14 14 if (n == 0) // return true if difference is 0; (gdb) print n $16 = 1 (gdb) step 16 if (n == 1) (gdb) step 17 return 0; (gdb) step 31 } (gdb) step main () at quiz.c:41 41 printf("test num=%d, result=%d\n",i,result); (gdb) step __printf (format=0xaaaaaaaaa940 "test num=%d, result=%d\n") at printf.c:33 33 printf.c: No such file or directory. (gdb) step __vfprintf_internal (s=0xfffff7fc6550 <_IO_2_1_stdout_>, format=0xaaaaaaaaa940 "test num=%d, result=%d\n", ap=..., mode_flags=mode_flags@entry=0) at vfprintf-internal.c:1328 1328 vfprintf-internal.c: No such file or directory. (gdb) step 1332 in vfprintf-internal.c (gdb) step 1343 in vfprintf-internal.c (gdb) step 1354 in vfprintf-internal.c (gdb) step 1365 in vfprintf-internal.c (gdb) continue Continuing. test num=4, result=0 [Inferior 1 (process 8578) exited normally] (gdb) continue The program is not being run. (gdb) quit ``` >Using layout next to display the code. ```c ┌──quiz.c──────────────────────────────────────────────┐ │36 int main() { │ │37 unsigned int n=2; // set the test │ │38 int result=0; │ B+ │39 for (int i=4; i<5;i++){ │ │40 result = isMultN(i); │ │41 printf("test num=%d, resul│ │42 } │ │43 } │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └──────────────────────────────────────────────────────┘ exec No process In: L?? PC: ?? (gdb) ```