{"id":20406039,"url":"https://github.com/coldnew/2015-embedded-summber-note","last_synced_at":"2025-03-05T02:19:10.698Z","repository":{"id":35286352,"uuid":"39547279","full_name":"coldnew/2015-embedded-summber-note","owner":"coldnew","description":"A note what I learn from Jserv in 2015 summber","archived":false,"fork":false,"pushed_at":"2015-08-11T08:46:37.000Z","size":268,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"sources","last_synced_at":"2025-01-15T12:14:36.064Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coldnew.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-23T05:20:42.000Z","updated_at":"2024-04-02T17:42:04.000Z","dependencies_parsed_at":"2022-09-10T11:11:39.862Z","dependency_job_id":null,"html_url":"https://github.com/coldnew/2015-embedded-summber-note","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coldnew%2F2015-embedded-summber-note","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coldnew%2F2015-embedded-summber-note/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coldnew%2F2015-embedded-summber-note/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coldnew%2F2015-embedded-summber-note/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coldnew","download_url":"https://codeload.github.com/coldnew/2015-embedded-summber-note/tar.gz/refs/heads/sources","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241950415,"owners_count":20047636,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T05:14:25.605Z","updated_at":"2025-03-05T02:19:10.681Z","avatar_url":"https://github.com/coldnew.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"#+TITLE: 2015 嵌入式系統暑期課程學習筆記\n\n#+BEGIN_QUOTE\n這是我去修 jserv 所開的 2015 嵌入式系統暑期課程的學習筆記，目前正在整理中\n原始資訊請見 [[hackpad][https://embedded2015.hackpad.com/2015--OsxFmQOf0cd]]\n#+END_QUOTE\n\n為什麼不全部寫在 hackpad? 因為我覺得他不好用.....Orz....\n這份文建會盡可能和我的 hackpad 同步，但會主要以這份為主。(因為這份是整理過的)\n\n目前這份文件仍舊在建構中....很多編排可能都會重新修正....\n\n#+BEGIN_QUOTE\n目前預計完成日: 2015, 10, 30\n#+END_QUOTE\n\n碎碎念..... 原本我想努力習慣 Markdown 這個東西，但是他還是很悲劇....看樣子我要準\n備寫一個 org-gitbook 轉換器了 Orz...\n\n\n\n* Introduction\n\n* 課堂考試題目\n\n這邊收集的是 Jserv 在課堂上的考試內容，以及我自己重新整理後的答案，僅供參考使用。\n\n** 請問以下的 DETECT 巨集用途是什麼 ?\n\n此題主要測試對位元運算的理解，那到底以下的 =DETECT= 巨集具有怎樣的用途呢?\n\n#+BEGIN_SRC c\n  #if LONG_MAX == 2147483647L\n  #define DETECT(X) (((X) - 0x01010101) \u0026 ~(X) \u0026 0x80808080)\n  #else\n  #if LONG_MAX == 9223372036854775807L\n  #define DETECT(X) (((X) - 0x0101010101010101) \u0026 ~(X) \u0026 0x8080808080808080)\n  #else\n  #error long int is not a 32bit or 64bit type.\n  #endif\n  #endif\n#+END_SRC\n\n*** 我的解答\n\n這個巨集上是用來測試輸入內容是否為 0，此巨集很常使用在 =strlen= 或是 =strcap= 等字串\n處理的函式上，我們可以從 Apple 的 [[http://opensource.apple.com/source/Libc/Libc-583/arm/string/strlen.s][strlen]] 或是其他 libc 中看到這巨集的影子。\n\n#+BEGIN_SRC asm\n  Laligned_loop:\n      /* ((x - 0x01010101) \u0026 ~x \u0026 0x80808080) == hasnull(word) */\n      sub     r3, r2, r1      /* x - 0x01010101 */\n      bic     r3, r3, r2      /* above \u0026 ~x */\n      tst     r3, r1, lsl #7  /* above \u0026 0x80808080 */\n      ldreq   r2, [r0], #4    /* load next word */\n      beq     Laligned_loop\n#+END_SRC\n\n\n所以到底為什麼這個巨集可以用來偵測 =Null char= ，使用他到底能夠為 =strlen= 等函式增\n加怎樣的優點？我們可以自己用 C 語言來試著去實作 =strlen= 這個函式看看，於是我們很快\n的完成了這個函式：\n\n#+BEGIN_SRC c\n  unsigned int strlen (const char *s)\n  {\n          char *p = s;\n\n          while (*p != '\\0') {\n                  p++;\n          }\n\n          return (p - s);\n  }\n#+END_SRC\n\n這樣的實作到底有什麼問題呢？首先注意到我們每一次只能檢查 =一個 byte= 大小的資訊，\n想想看在 32-bit 系統上，CPU 一次是處理 4-byte 大小的資訊，不覺得有點浪費嗎?(用在\n64-bit 上面問題就更嚴重了）\n\n*** 參考資料\n\n\n** 請實現 ARM 版本的 Brainf*ck JIT compiler\n\n\n** 請設計一個運作在 32-bit 系統上演算法，找出兩個數裡面較大的數\n\n這個題目要求不得使用 if-else 或 \u003c \u003e 一類比較的運算子\n\nHint: (a - b) 的正負號，搭配乘法\n\n*** 參考解答\n\n題目要求我們找出較大的數值，但是不能使用 \u003e \u003c 之類的 operator, 為了便於之後的比較，\n我們先實作一個簡易的函式用來尋找輸入項目是正整數還是負整數\n\n#+BEGIN_SRC c\n  int32_t sign(int32_t a)\n  {\n          return 1 ^ ((a \u003e\u003e 31) \u0026 0x1); // 1: positive, 0: negative\n  }\n#+END_SRC\n\n#+BEGIN_SRC c\n  int32_t max(int32_t a, int32_t b)\n  {\n          return a * sign(a - b) + b * (1 ^ sign(a - b));\n  }\n#+END_SRC\n\n這樣的解法在 (a - b) 下可能會出現 Overflow 的狀況，怎樣說呢？假如我們對 a、b 兩個\n變數這樣進行設定\n\n#+BEGIN_SRC c\n  #include \u003cstdio.h\u003e\n  #include \u003climits.h\u003e\n  #include \u003cstdint.h\u003e\n  #include \u003cassert.h\u003e\n\n  int32_t msb(int32_t a)\n  {\n          return (a \u003e\u003e 31) \u0026 0x1;\n  }\n\n  int32_t sign(int32_t a)\n  {\n          return 1 ^ msb(a);\n  }\n\n  int32_t max1(int32_t a, int32_t b)\n  {\n          return (a * sign(a - b) + b * (1 ^ sign(a - b)));\n  }\n\n  int32_t max2(int32_t a, int32_t b)\n  {\n          return a * msb(b) + b * msb(a);\n  }\n\n  int32_t max(int32_t a, int32_t b)\n  {\n          return  max1(a, b) * !(msb(a) ^ msb(b)) + // a and b has the same sign\n                  max2(a, b) *  (msb(a) ^ msb(b));  // a and b has different sign\n  }\n\n  int main(int argc, char *argv[])\n  {\n          assert( 5 == max(3, 5) );\n          assert( 5 == max(5, 3) );\n\n          assert( -3 == max(-3, -5) );\n          assert( -3 == max(-5, -3) );\n\n          assert( INT_MAX - 2 == max(INT_MAX - 2, -15) );\n          assert( INT_MAX - 2 == max(-15, INT_MAX - 2) );\n\n          return 0;\n  }\n#+END_SRC\n\n*** 延伸閱讀\n\n1. [[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]]\n\n2. [[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.]]\n\n3. [[http://graphics.stanford.edu/~seander/bithacks.html][Bit Twiddling Hacks]]\n\n\n** 給定一個 5 bit 的數值，最少需要幾次猜測，就可知道正確答案？\n\n* 課堂作業\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoldnew%2F2015-embedded-summber-note","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoldnew%2F2015-embedded-summber-note","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoldnew%2F2015-embedded-summber-note/lists"}