assembly

課程資料

組合語言與系統程式

開課:陳永昇老師

修課年度:99資工系

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

    1. Basic Concepts
    1. x86 Processor Architecture
    1. Assembly Language Fundamentals
    1. Data Transfers, Addressing, and Arithmetic
    1. Procedures
    1. Conditional Processing
    1. Integer Arithmetic
    1. Advanced Procedures
    1. Strings and Arrays
    1. Structures and Macros
    1. High-Level Language Interface
    1. 16-Bit MS-DOS Programming
    1. Expert MS-DOS Programming

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

    1. Background
    1. Assemblers
    1. Loaders and Linkers
    1. 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 是什麼了,就算最後發現要求不太一樣,也依然有理解系統程式課程的好處。

延伸閱讀