# 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)
```