我也認真上過課——《微機原理》學習筆記

彙編語言程序設計

這篇文章是一年之前學微機原理時寫的,現在改一下格式重發到CSDN博客上。主要內容是彙編語言。

1 彙編語言程序及其開發

源程序經過彙編成爲目標程序,再將目標程序連接成爲exe程序,最後進行執行和調試。

2 彙編語言源程序的結構

2.1 執行性語句和說明性語句

彙編語句分爲執行性語句說明性語句

執行語句最後會轉變爲機器碼,即01數據存儲在內存中;

說明性語句由編譯器處理,不會生成機器碼。

執行性語句格式:

a:mov ax,0; // 將ax寄存器置0

說明性語句格式:

a dw 3; // 在內存中申請一個字的空間,在裏面放入0003,這段空間的起始地址爲a。

2.2 定義段

比如:

stacksg segment  para   stack 'stack'
段名     定位類型 連接方式     類別名

段名:stacksg即此段的起始地址 。

定位類型:有四種定位類型:

  • para類型:表示此段的起始地址的最低四位必須是0;
  • page類型:表示此段的起始地址的最低八位必須是0;
  • word類型:表示此段的地址必須爲偶數;
  • byte類型:表示此段可以從任何地址開始。

默認的缺省定位類型爲para類型。

連接方式:如果我們有多個目標程序,我們對他們進行連接的時候就要使用連接方式。現在我們只需要學習at連接方式,at後面加一個地址,表示這個段的段地址,at連接方式不能用於代碼段。

類別名:也是在連接時使用的。

常見的定義段的方式:datasg segment at 1000h

2.3 equ僞指令

equ是等價的意思,相當於c++中的引用。

比如:

const equ 10h

這裏我們定義了一個const,它等價於10h。

需要注意的是,用equ定義的符號名在同一程序只能定義一次,不許重複定義

2.4 =僞指令

比如:

const   =   10h

這裏的const允許在後面再進行更改,也就是說可以重複定義。

2.5 數據標號

比如:

a   dw   0,0,0,0

這句話在內存中分配4個字的空間,都賦值成0。

這裏a就是數據標號,它同時描述了內存地址和單元長度。從今以後,a就是這四個零的地址,並且說到a必須是字,把它賦給字節或者雙字都不行。

一種特殊的數據標號指令:

a   dw   ?

這裏在內存中費配了一個字的空間。使用?的意思是隻開闢空間而不進行初始化。

2.6 dup僞指令

比如:

a   db   100   dup   (00h)

表示開闢一百個字節空間,並全都賦值成00h

2.7 ret和retf

ret指令用棧中的數據,修改ip的內容,從而實現近轉移。

retf指令用棧中的數據,修改cs和ip的內容,從而實現遠轉移。

CPU執行ret指令時,相當於執行pop IP

CPU執行retf指令時,相當於執行pop IP pop CS

2.8 過程定義僞指令proc和endp

過程就是子程序。一般會使用call指令調用子程序,子程序的最後一條指令一般是ret,用於返回shell。

比如:

delay proc near        
      push cx    ; // 將cx的值入棧,以免丟失,等子程序運行完,返回原程序時再出棧
      mov cx,30h ; // 通過設置cx的值改變延時的時間
wait:loop wait
      pop cx     ; // cx出棧
      ret        ; // 返回原程序
delay endp

其中的near表示是段內轉移,如果是段間轉移的話要換成far
delayendp必須成對出現。

2.9 org指令

用來設置偏移地址。
比如:

data segment
     a db 23,56
     org 2000h
data ends

表示a的偏移地址爲2000h

3 常數、變量及標號

一個字符對應一個字節。
比如:‘a’對應41h

4 表達式和運算符

4.1 算數運算符

±*/:加減乘除

mod:取餘

shl和shr:shl和shr是邏輯移位指令。

shl是邏輯左移指令,它的功能爲:

  1. 將一個寄存器或內存單元中的數據向左移位;
  2. 將最後移出的一位寫入CF中;
  3. 最低位用0補充。

比如:

mov al,01001000b
shl al,1 ;將al中數據左移一位

執行後(al)=10010000b,CF=0。

注意:

如果移動位數大於1時,必須將移動位數放在cl中。

比如:

mov al,01010001b
mov cl,3
shl al,cl

執行後(al)=10001000b,因爲最後移出的一位是0,所以CF=0。

shr是邏輯右移指令,它和shl所進行的操作剛好相反。

4.2 邏輯運算符

  • and:與
  • or:或
  • xor:異或
  • not:非

4.3 關係運算符

使用關係運算符進行邏輯判定,如果判定結果是真返回全1(0FFFFH),否則返回0。

  • eq:等於
  • ne:不等於
  • lt:小於
  • le:小於等於
  • gt:大於
  • ge:大於等於

關係運算符一般不單獨使用,常與其他運算符結合使用

比如:

// a大於60時,給al賦值50;a小於等於60時,給al賦值70
mov   al,((a gt 60) and 50) or ((a le 60) and 70);

4.4 seg和offset

seg給出段地址,offset給出偏移地址。

4.5 type

type操作符返回一個表示操作數的類型的數值。

字節類型返回1,字類型返回2,雙字類型返回4,near標號返回-1(0FFFFH),對於far標號返回-2(0FFFEH)。

4.6 length和size

一般與dup連用。

比如定義

a   dw   50   dup(0000)

則:length(a)=50 size(a)=100

其中size = length*type

另外對於用非dup定義的length返回1。

4.7 high和low

high和low分別返回字的高字節和低字節。

比如:

a = 2050h
mov al,low a;// al = 50h
mov ah,high a;// ah = 20h

4.8 $運算符

$是彙編語言中的一個預定義符號,等價於當前正彙編到的段的當前偏移值。

比如最常用的JMP $就是指轉移到當前執行語句的地址,在這的效果就是原地跳轉,不再向後執行了。

指令“jmp $+3”中的“$”表示當前這條指令在代碼段中的偏移量。

指令“jmp $+3”表示要向前跳轉到距離這條指令3個字節的地方。

若是“jmp $-3”,則表示要向後跳轉到距離這條指令3個字節的地方。

$常見於動態定義數據長度,例如:

MyData       db   '123456789abcdefgh'
DataLength   EQU   $  -  MyData

4.9 ptr

指明是字單元還是字節單元

比如:

mov   word  ptr  ds:[0],12h

5 8086/8088CPU彙編程序的輸入與輸出

使用DOS的功能通常要進行如下4個步驟

  1. 在AH中設置功能號
  2. 在指定寄存器中設置入口參數
  3. int 21h
  4. 得到出口參數,可以用來分析執行的情況

5.1 輸入單個字符

功能號:01h

入口參數:用戶從鍵盤輸入

出口參數:al = 所輸入字符的ASCII碼

功能:用戶從鍵盤輸入一個字符,輸入字符後返回,同時在屏幕上顯示所輸入的字符。ctrl+c退出。

比如:

mov   ah,1
int   21h

5.2 輸入字符串

功能號:0ah

入口參數:ds:dx指向字符串緩衝區的首地址,緩衝區的第一個字節存放最多接收的字符個數(包括回車)。入口參數由用戶輸入。

出口參數:ds:dx指向的第二字符存放實際輸入的字符個數(不包括回車),從第三個字符開始存放輸入的字符串。若實際輸入的字符數比最大字符數多,多出來的字符會被丟棄並響鈴。

比如:

buffer db 81        ;定義緩衝區,最多允許輸入81個字符(包括回車)
db 0                ;定義實際存放的字符數
db 81 dup (0)       ;存放輸入的字符串
mov dx,seg buffer   ;取得buffer的段地址
mov ds,dx                             
mov dx,offset buffer;取得buffer的偏移地址
mov ah,0ah
int 21h

5.3 顯示單個字符

功能號:02h

入口參數:dl=要顯示的字符的ASCII碼

功能:在顯示器當前光標出顯示單個字符,然後光標右移一個位置。ctrl+c退出。

比如:

mov   ah,02h
mov   dl,41h
int      21h

5.4 顯示字符串

功能號:09h

入口參數:ds:dx指向字符串的首地址,注意字符串必須以$結束。

功能:在顯示器上輸出指定的字符串。

比如:

string   db 'hello$'
mov      dx,seg string
mov      ds,dx
mov      dx,offset string
mov      ah,09h
int      21h

5.5 磁盤輸入輸出


說明:

  1. 文件名字符串以0作爲結束標誌。
  2. cx中的文件屬性有:00(標準文件)、01(只讀文件)、02(隱含文件)、04(系統文件)。
  3. ax中的錯誤碼有:1(無效功能號)、2(文件沒找到)、3(路徑未找到或文件不存在)、4(打開文件太多)、5(拒絕存取)。

6 高級彙編技術

6.1 宏彙編

宏是爲了減輕程序猿的負擔,它有點像高級語言中的函數。

我們先會定義一個宏,然後在需要它的時候使用它。編譯器看到我們使用宏,會在這個地方把代碼補全。

定義宏:

a   macro   x,y,z              ;;a是宏名,xyz都是形參
    mov     ax,0
    endm                       ;;宏以endm結束

宏定義一般出現在程序的開頭。

宏定義中的註釋要以;;開始

調用宏:

a   4,al,al
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章