https://github.com/coldnew/2015-embedded-summber-note
A note what I learn from Jserv in 2015 summber
https://github.com/coldnew/2015-embedded-summber-note
Last synced: over 1 year ago
JSON representation
A note what I learn from Jserv in 2015 summber
- Host: GitHub
- URL: https://github.com/coldnew/2015-embedded-summber-note
- Owner: coldnew
- Created: 2015-07-23T05:20:42.000Z (almost 11 years ago)
- Default Branch: sources
- Last Pushed: 2015-08-11T08:46:37.000Z (almost 11 years ago)
- Last Synced: 2025-01-15T12:14:36.064Z (over 1 year ago)
- Language: JavaScript
- Size: 262 KB
- Stars: 2
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
Awesome Lists containing this project
README
#+TITLE: 2015 嵌入式系統暑期課程學習筆記
#+BEGIN_QUOTE
這是我去修 jserv 所開的 2015 嵌入式系統暑期課程的學習筆記,目前正在整理中
原始資訊請見 [[hackpad][https://embedded2015.hackpad.com/2015--OsxFmQOf0cd]]
#+END_QUOTE
為什麼不全部寫在 hackpad? 因為我覺得他不好用.....Orz....
這份文建會盡可能和我的 hackpad 同步,但會主要以這份為主。(因為這份是整理過的)
目前這份文件仍舊在建構中....很多編排可能都會重新修正....
#+BEGIN_QUOTE
目前預計完成日: 2015, 10, 30
#+END_QUOTE
碎碎念..... 原本我想努力習慣 Markdown 這個東西,但是他還是很悲劇....看樣子我要準
備寫一個 org-gitbook 轉換器了 Orz...
* Introduction
* 課堂考試題目
這邊收集的是 Jserv 在課堂上的考試內容,以及我自己重新整理後的答案,僅供參考使用。
** 請問以下的 DETECT 巨集用途是什麼 ?
此題主要測試對位元運算的理解,那到底以下的 =DETECT= 巨集具有怎樣的用途呢?
#+BEGIN_SRC c
#if LONG_MAX == 2147483647L
#define DETECT(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
#define DETECT(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#+END_SRC
*** 我的解答
這個巨集上是用來測試輸入內容是否為 0,此巨集很常使用在 =strlen= 或是 =strcap= 等字串
處理的函式上,我們可以從 Apple 的 [[http://opensource.apple.com/source/Libc/Libc-583/arm/string/strlen.s][strlen]] 或是其他 libc 中看到這巨集的影子。
#+BEGIN_SRC asm
Laligned_loop:
/* ((x - 0x01010101) & ~x & 0x80808080) == hasnull(word) */
sub r3, r2, r1 /* x - 0x01010101 */
bic r3, r3, r2 /* above & ~x */
tst r3, r1, lsl #7 /* above & 0x80808080 */
ldreq r2, [r0], #4 /* load next word */
beq Laligned_loop
#+END_SRC
所以到底為什麼這個巨集可以用來偵測 =Null char= ,使用他到底能夠為 =strlen= 等函式增
加怎樣的優點?我們可以自己用 C 語言來試著去實作 =strlen= 這個函式看看,於是我們很快
的完成了這個函式:
#+BEGIN_SRC c
unsigned int strlen (const char *s)
{
char *p = s;
while (*p != '\0') {
p++;
}
return (p - s);
}
#+END_SRC
這樣的實作到底有什麼問題呢?首先注意到我們每一次只能檢查 =一個 byte= 大小的資訊,
想想看在 32-bit 系統上,CPU 一次是處理 4-byte 大小的資訊,不覺得有點浪費嗎?(用在
64-bit 上面問題就更嚴重了)
*** 參考資料
** 請實現 ARM 版本的 Brainf*ck JIT compiler
** 請設計一個運作在 32-bit 系統上演算法,找出兩個數裡面較大的數
這個題目要求不得使用 if-else 或 < > 一類比較的運算子
Hint: (a - b) 的正負號,搭配乘法
*** 參考解答
題目要求我們找出較大的數值,但是不能使用 > < 之類的 operator, 為了便於之後的比較,
我們先實作一個簡易的函式用來尋找輸入項目是正整數還是負整數
#+BEGIN_SRC c
int32_t sign(int32_t a)
{
return 1 ^ ((a >> 31) & 0x1); // 1: positive, 0: negative
}
#+END_SRC
#+BEGIN_SRC c
int32_t max(int32_t a, int32_t b)
{
return a * sign(a - b) + b * (1 ^ sign(a - b));
}
#+END_SRC
這樣的解法在 (a - b) 下可能會出現 Overflow 的狀況,怎樣說呢?假如我們對 a、b 兩個
變數這樣進行設定
#+BEGIN_SRC c
#include
#include
#include
#include
int32_t msb(int32_t a)
{
return (a >> 31) & 0x1;
}
int32_t sign(int32_t a)
{
return 1 ^ msb(a);
}
int32_t max1(int32_t a, int32_t b)
{
return (a * sign(a - b) + b * (1 ^ sign(a - b)));
}
int32_t max2(int32_t a, int32_t b)
{
return a * msb(b) + b * msb(a);
}
int32_t max(int32_t a, int32_t b)
{
return max1(a, b) * !(msb(a) ^ msb(b)) + // a and b has the same sign
max2(a, b) * (msb(a) ^ msb(b)); // a and b has different sign
}
int main(int argc, char *argv[])
{
assert( 5 == max(3, 5) );
assert( 5 == max(5, 3) );
assert( -3 == max(-3, -5) );
assert( -3 == max(-5, -3) );
assert( INT_MAX - 2 == max(INT_MAX - 2, -15) );
assert( INT_MAX - 2 == max(-15, INT_MAX - 2) );
return 0;
}
#+END_SRC
*** 延伸閱讀
1. [[http://stackoverflow.com/questions/4772780/find-the-maximum-of-two-numbers-without-using-if-else-or-any-other-comparison-op][StackOverflow - Find the maximum of two numbers without using if-else or any other comparison operator]]
2. [[http://www.programmerinterview.com/index.php/general-miscellaneous/find-max-without-comparison/][ProgrammerInterview.com - Find the max of two numbers without using any of the comparison operators like if-else.]]
3. [[http://graphics.stanford.edu/~seander/bithacks.html][Bit Twiddling Hacks]]
** 給定一個 5 bit 的數值,最少需要幾次猜測,就可知道正確答案?
* 課堂作業