彙編學了好久了,最近在看Linux0.12核心的時候,發現對彙編沒有什麼感覺,還有對一些定時器的編程,看不太懂。閑來無事,複習複習簡單的彙編。
這個程式只有程式碼片段,使用end標號來定位程式開始啟動並執行地址。
所以,在這裡,end標號的作用有兩個:
1:通知編譯器程式什麼時候結束
2:通知編譯器程式的入口在什麼地方
assume cs:codecode segmentdw 0001,0001,0001,0001,0001,0001,0001,0001start:mov bx,0mov ax,0mov cx,8s:add ax,cs:[bx]add bx,2loop smov ax,4c00hint 21hcode endsend
在單任務系統中,可執行檔的執行過程如下:
1:由其他的程式(debug、command)將可執行檔載入記憶體;
2:設定CS、IP指向程式的第一條要執行的指令(即程式的入口),從而使程式得以運行。
3:程式運行結束後,返回至載入者。
註:在使用debug的時候,會發現程式時ip指向的指令並不是合法的指令,這是因為程式碼片段儲存的是資料,我們需要使用R命令修改ip的值,使它指向程式啟動並執行第一條指令。
現在改進一下程式,給程式增加一個棧,放在程式碼片段中。通過棧,使得上一個程式段中定義的字形數組逆序排列。
assume cs:codecode segmentdw 0001,0002,0003,0004,0005,0006,0007,0008;用dw定義8個字形資料;在程式載入後,將取得8個字的記憶體空間,作為後面的程式棧來使用。dw 0,0,0,0,0,0,0,0start:mov ax,csmov ss,axmov sp,32mov bx,0mov cx,8s:push cs:[bx]add bx,2loop smov bx,0mov cx,8s0:pop cs:[bx]add bx,2loop s0mov ax,4c00hint 21hcode endsend
我們在來源程式中使用assume指令將cs、ds和ss分別和code、data、stack相連後,並沒有讓cs指向程式碼片段,ss指向堆棧段。注意,assume是偽指令,是由編譯器執行的,cpu並不知道他們。所以我們需要在代碼中分別給cs、ss和ds賦值。
注意:在8086中,不允許將一個數值直接賦值給段寄存器。所以在程式開始時初始化程式碼片段寄存器的時候,我們應該使用
mov ax,csmov ss,ax
而不是使用
mov ds,data