一 理解基礎編譯
僞指令->用於編譯器識別
彙編指令->編譯爲機器碼
assume :含義爲“假設”。它假設某一段寄存器和程序中的某一個用segment ... ends定義的段相關聯。
segment和ends的功能是定義一個段。segment說明一個段開始,ends說明一個段結束。
End是一個彙編程序的結束標記,編譯器在編譯彙編程序的過程中,如果碰到了僞指令end,就結束對源程序的編譯。
連接的作用有以下幾個:
- 當源程序很大時,可以將它分爲多個源程序文件來編譯,每個源程序編譯成爲目標文件後,再用連接程序將它們連接到一起,生成一個可執行文件;
- 程序中調用了某個庫文件中的子程序,需要將這個庫文件和該程序生成的目標文件連接到一起,生成一個可執行文件;
在MASM中:
mov al, [0] =>al=0
mov al, ds:[0] =>把段地址爲ds:0處的內容給al
二 理解段編程
2.1 代碼段中使用數據
“dw”的含義是定義字型數據。(dw即define word)
(1)這8個數據的偏移地址是多少呢?
因爲用dw定義的數據處於代碼段的最開始,所以偏移地址爲0,這8個數據就在代碼段的偏移0、2、4、6、8、A、C、E處。
(2)如何將8個數據相加?
在循環開始前,設置(bx)=0,cs:bx指向第一個數據所在的字單元。每次循環中(bx)=(bx)+2,cs:bx指向下一個數據所在的字單元。
(3)如何將上述程序變成一個可執行程序呢?
源程序的最後用“end start",end將告訴CPU程序的入口,這個入口將被寫入可執行文件的描述信息,可執行文件中的程序被加載入內存後,CPU的CS:IP被設置指向這個入口,從而開始執行程序中的第一條指令。
標號“start”"在“code"段中,這樣CPU就將code段中的內容當作指令來執行了。
2.2 代碼段中使用棧
例:完成下面的程序,利用棧,將程序中定義的數據逆序存放。
assume cs:codesg
codesg segment
dw 0123h,O456h,O789h ,Oabch,0defh,O fedh ,0cbah,0987h
?
code ends
(1)程序設計的思路大致如下:
程序運行時,定義的數據存放在cs:0~cs:15單元中,共8個字單元。依次將這8個字單元中的數據入棧,然後再依次出棧到這8個字單元中,從而實現數據的逆序存放。
(2)問題是如何獲取棧空間呢?
我們可以在程序中通過定義數據來取得一段空間,然後將這段空間當作棧空間來用。我們要將cs:16~ cs:31的內存空間當作棧來用,初始狀態下棧爲空,所以ss:sp要指向棧底,則設置ss:sp指向cs:32。
2.3 不同段的編程
背景:一個段的容量不能大於64KB,是我們在學習中所用的8086模式的限制,並不是所有的處理器都這樣。
方法:我們用和定義代碼段一樣的方法來定義多個段,然後在這些段裏面定義需要的數據,或通過定義數據來取得棧空間。
注意:如果段中的數據佔N個字節,則程序加載後,則段實際佔有的空間:
16×(N/16+1)
三 字符串編程
3.1 大小寫轉換
A:01000001 a:01100001區別在於第5位不同
C語言如下:
四 數據處理
4.1 數據存放
(1)源數據data在哪裏?
DS中年份(0-53H)、收入(54H-0A7H)、僱員(0A8H-OD1H)
(2)目標數據table爲什麼放在ES裏?
因爲ds被data佔用了。
4.2 call與ret
數據存放在bx中