assembly

課程資料

組合語言與系統程式

開課:陳永昇老師

修課年度:99資工系

組合語言的部份使用的是《Assembly Language for x86 Processors》,教了以下章節:

  • 1. Basic Concepts
  • 2. x86 Processor Architecture
  • 3. Assembly Language Fundamentals
  • 4. Data Transfers, Addressing, and Arithmetic
  • 5. Procedures
  • 6. Conditional Processing
  • 7. Integer Arithmetic
  • 8. Advanced Procedures
  • 9. Strings and Arrays
  • 10. Structures and Macros
  • 13. High-Level Language Interface
  • 14. 16-Bit MS-DOS Programming
  • 17. Expert MS-DOS Programming

系統程式的部份使用的是《System Software: An Introduction to Systems Programming》,教了以下章節:

  • 1. Background
  • 2. Assemblers
  • 3. Loaders and Linkers
  • 8. Software Engineering Issues

額外有出了一份寫 DOS 病毒的作業,可以學習一些感染 EXE 檔的技巧。

本門課的組語主要是用 MASM 組譯器的格式,同時也會運用到教科書中的諸多 routines。由於老師並不會特別教導組譯環境的設置,同學需自行閱讀教科書及作者網站,我寫了一種環境設置的方法和其他一些跟這門課相關的議題:〈組合語言與系統程式〉

上課方式

使用投影片上課,大抵上上課氣氛很自由,不會有什麼壓力。由配分可見它是以實作為主的課程,本文也以介紹作業為主。

每份作業都需 demo(包含期末 project 在暑假 demo),是在 demo 時從 E3 上下載之前上傳的程式碼,由於並不會事先公佈所有的測資,所以要細心一點。組語作業如果有多做功能可以主動向助教提出,可以得到不等的額外加分。

另外,事後會公佈全班的 code 供大家學習參考。上到最後一堂課時會有一張特別的投影片:師:「永生難忘」。

不點名,但是有來上課的話可以提早得知作業。作業投影片通常在宣佈後一星期放上E3。此外,死限延期或其他特殊事項也是只有在上課時公佈,或者在上課時提早公佈。

評分方式

這門課的配分是這樣的:

  • 60% 4次組語作業
  • 25% SIC/XE 組繹器(可用任意語言寫)
  • 15% 期末考

沒有期中考,不過另外有一個期中組語上機考,是考較為簡單組語程式題目,也可攜帶參考資料和作業原始碼,但若未通過則 4 次組語作業不能算分。

根據前人的經驗,只要作業都滿分,就算期末考六十幾分也能得到 99,有付出就有收穫。

考試作業

作業通常會在上課公佈,晚一點則會公佈在 E3,死限通常在星期日的夜晚。

第一個作業是三個組語小程式:

  1. 輸入兩個 32-bit 正整數,輸出其最小公倍數。
  2. 輸入一個日期,輸出那天星期幾。
  3. 輸入一個正整數,輸出所有比它小的質數。

第二個作業是用組語寫一個 finite-state machine 可以解析一行輸入的組合語言(MASM 格式),如:

1
2
3
4
5
6
7
8
9
Input=> L1: sub ecx, var   ; substract ecx by var

Result=>

        LABEL             L1
        INSTRUCTION       sub
        REGISTER          ecx
        IDENTIFIER        var
        COMMENT           substract ecx by var

如果有錯誤輸入,該錯誤 token 輸出 unknown,但其後的正確 token 仍需正確辨識。不需判斷 grammar 錯誤,如 mul 應該只能接受一個 operand:

1
2
3
4
5
6
7
Input=> mul eax, 5

Result=>

        INSTRUCTION       mul
        REGISTER          eax
        INTEGER           5

禁止使用 .IF .WHILE 等 directives

第三個作業是寫一個計算機,可以計算輸入運算式結果,支援 + - * / ( ),如 2+4-6*2 = -6。輸入運算式最長為 100 字,數字長度最長也是 100 位(需使用大數運算)。

第四個作業是 16-bit DOS programming:

  1. 寫一個 TSR 鋼琴程式,鍵盤需可正常輸入,但按下按鍵會發出聲音。
  2. bonus(這題本來不是 bonus,後來更改評分):寫一個 TSR 病毒程式,執行後會常駐於系統中,在你開啟另一個 exe 檔時感染該執行檔,使其執行被插入的程式碼(如列印一行字),但仍保持原有的功能。

期末 Project期限在期末考後的一個星期後。是要以如《 System Software: An Introduction to Systems Programming》 一書的格式,撰寫一個 SIC/XE 組譯器可以產生 relocatable object program。

其中 60% 要支援所有 addressing modes, 教到的 assembler directives,以及以下除外的指令:浮點數運算、SW register 相關指令,SIO, TIO, HIO,LPS, STI, SVC,SSK。

40% 佔分則為:Literals, Symbol-defining statements, Expressions, Program Blocks and Control Sections。

我有把一部分的作業原始檔放在 github 上,可供參考:99-asm

上機考有三題:

  1. 印出 Pascal’s triangle
  2. 給一個長度 4 字串,輸出任一重排後字串。
  3. 給兩個最多 40 位的二進位數字,輸出相減後結果。

不需全部解出也算通過。

期末考的題目主要配分是系統程式占的較重,所以不要只看組語的部份。仔細觀察可以發現,題目大多為課本習題,特別是系統程式的部份。這次的組語大多為選擇題,系統程式相對較難。老師會給考古題,不過有重疊的題數大概只有一兩題。

結語

想要預習或自修的話,《 Assembly Language for x86 Processors》 這本書每章背後都有程式練習題,筆者做過幾章,覺得挺有幫助,感覺跟程式語言有關的課練習都是十分重要。組語的教學也可以參考小木偶的網頁

系統程式部份可以邊寫組譯器邊看,這樣會有更深的理解。自己修這門課花了很多心思在作業上,不知不覺就會忘了讀系統程式。但這門課的系統程式部份實際上佔分滿多的。

雖然沒有期中考確實讓期中的壓力減輕不少。但對筆者而言,組譯器的撰寫顯得有些匆忙,逼近期末考周時,因為要準備考試,沒時間寫期末 Project。即使考完期末考,最後一個星期忙著搬宿舍,能寫的時間不是很有彈性,不得已得花很長得時間連續不斷寫 Project,寫到最後動力遞減,很容易想放棄。

現在想起來,我認為最好可以一開學就開始寫 SIC/XE 組譯器,一方面可以邊寫邊看課本來準備期末考,二方面透過時段的切割可以避免學期末擠在一起時的壓力。

況且其實一開學就會說期末 project 是什麼了,就算最後發現要求不太一樣,也依然有理解系統程式課程的好處。

延伸閱讀